Queue improvements
This commit is contained in:
parent
8af18644a3
commit
e5da45df2f
@ -1,15 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// This header file contains macros for making FIFO queues from structures
|
||||||
|
// A queue is set up via a preprocessor definition
|
||||||
|
// #define QueueName header_name, spot_name, struct type
|
||||||
|
// where
|
||||||
|
// QueueName is the queue identifying name
|
||||||
|
// header_name is a unique name used for the queue head
|
||||||
|
// spot_name is the name of the queue placeholder in the struct
|
||||||
|
// struct type is the type of struct the queue is made from
|
||||||
|
//
|
||||||
|
// Each queue requires a declaration
|
||||||
|
// QUEUE_DECLARE(QueueName);
|
||||||
|
// and a definition
|
||||||
|
// QUEUE_DEFINE(QueueName);
|
||||||
|
|
||||||
#define _QUEUE_DECL(queue, entry, type) \
|
#define _QUEUE_DECL(queue, entry, type) \
|
||||||
struct queue{ \
|
struct queue{ \
|
||||||
type *first; \
|
type *first; \
|
||||||
type *last; \
|
type *last; \
|
||||||
}
|
} queue
|
||||||
#define QUEUE_DECL(...) _QUEUE_DECL(__VA_ARGS__)
|
#define QUEUE_DECLARE(...) _QUEUE_DECL(__VA_ARGS__)
|
||||||
#define _QUEUE_HEAD(queue, entry, type) \
|
#define _QUEUE_HEAD(queue, entry, type) \
|
||||||
struct queue queue
|
struct queue queue = {0, 0}
|
||||||
#define QUEUE_HEAD(...) _QUEUE_HEAD(__VA_ARGS__)
|
#define QUEUE_DEFINE(...) _QUEUE_HEAD(__VA_ARGS__)
|
||||||
#define QUEUE_HEAD_EMPTY(...) _QUEUE_HEAD(__VA_ARGS__) = {0,0}
|
|
||||||
|
|
||||||
#define _QUEUE_SPOT(queue, entry, type) \
|
#define _QUEUE_SPOT(queue, entry, type) \
|
||||||
type *entry
|
type *entry
|
||||||
@ -17,23 +30,23 @@
|
|||||||
|
|
||||||
#define _QUEUE_EMPTY(queue, entry, type) \
|
#define _QUEUE_EMPTY(queue, entry, type) \
|
||||||
(!(queue.last))
|
(!(queue.last))
|
||||||
#define QUEUE_EMPTY(...) _QUEUE_EMPTY(__VA_ARGS__)
|
#define queue_empty(...) _QUEUE_EMPTY(__VA_ARGS__)
|
||||||
#define QUEUE_NOT_EMPTY(...) (!(_QUEUE_EMPTY(__VA_ARGS__)))
|
#define queue_not_empty(...) (!(_QUEUE_EMPTY(__VA_ARGS__)))
|
||||||
|
|
||||||
#define _QUEUE_ADD(queue, entry, type, item) \
|
#define _QUEUE_ADD(queue, entry, type, item) \
|
||||||
if(!queue.last) \
|
if(!queue.last) \
|
||||||
queue.first = item; \
|
queue.first = (item); \
|
||||||
else \
|
else \
|
||||||
queue.last->entry = item; \
|
queue.last->entry = (item); \
|
||||||
queue.last = item; \
|
queue.last = item; \
|
||||||
item->entry = 0;
|
(item)->entry = 0;
|
||||||
#define QUEUE_ADD(...) _QUEUE_ADD(__VA_ARGS__)
|
#define queue_add(...) _QUEUE_ADD(__VA_ARGS__)
|
||||||
|
|
||||||
#define _QUEUE_DROP(queue, entry, type) \
|
#define _QUEUE_DROP(queue, entry, type) \
|
||||||
if(!(queue.first = queue.first->entry)) \
|
if(queue.first && !(queue.first = queue.first->entry)) \
|
||||||
queue.last = 0;
|
queue.last = 0;
|
||||||
#define QUEUE_DROP(...) _QUEUE_DROP(__VA_ARGS__)
|
#define queue_drop(...) _QUEUE_DROP(__VA_ARGS__)
|
||||||
|
|
||||||
#define _QUEUE_PEEK(queue, entry, type) \
|
#define _QUEUE_PEEK(queue, entry, type) \
|
||||||
(queue.first)
|
(queue.first)
|
||||||
#define QUEUE_PEEK(...) _QUEUE_PEEK(__VA_ARGS__)
|
#define queue_peek(...) _QUEUE_PEEK(__VA_ARGS__)
|
||||||
|
60
src/kernel/include/queue.tt
Normal file
60
src/kernel/include/queue.tt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// vim: ft=c
|
||||||
|
#include <ttest.h>
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
#define TestQ test_queue, test_queue_next, struct item
|
||||||
|
QUEUE_DECLARE(TestQ);
|
||||||
|
QUEUE_DEFINE(TestQ);
|
||||||
|
|
||||||
|
struct item
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
QUEUE_SPOT(TestQ);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct item item1 = {1, 0};
|
||||||
|
struct item item2 = {2, 0};
|
||||||
|
|
||||||
|
TEST(peek_returns_queued_item)
|
||||||
|
{
|
||||||
|
queue_add(TestQ, &item1);
|
||||||
|
struct item *i = queue_peek(TestQ);
|
||||||
|
ASSERT_EQ_INT(i->id, 1);
|
||||||
|
}
|
||||||
|
TEST(peek_returns_first_queued_item)
|
||||||
|
{
|
||||||
|
queue_add(TestQ, &item1);
|
||||||
|
queue_add(TestQ, &item2);
|
||||||
|
struct item *i = queue_peek(TestQ);
|
||||||
|
ASSERT_EQ_INT(i->id, 1);
|
||||||
|
}
|
||||||
|
TEST(peek_returns_zero_for_empty_queue)
|
||||||
|
{
|
||||||
|
struct item *i = queue_peek(TestQ);
|
||||||
|
ASSERT_EQ_PTR(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(drop_drops_item_from_queue)
|
||||||
|
{
|
||||||
|
queue_add(TestQ, &item1);
|
||||||
|
queue_add(TestQ, &item2);
|
||||||
|
queue_drop(TestQ);
|
||||||
|
struct item *i = queue_peek(TestQ);
|
||||||
|
ASSERT_EQ_INT(i->id, 2);
|
||||||
|
}
|
||||||
|
TEST(drop_empty_queue_does_not_crash)
|
||||||
|
{
|
||||||
|
queue_drop(TestQ);
|
||||||
|
ASSERT_EQ_INT(!!queue_empty(TestQ), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(empty_reports_empty_queue_empty)
|
||||||
|
{
|
||||||
|
ASSERT_EQ_INT(!!queue_empty(TestQ), 1);
|
||||||
|
}
|
||||||
|
TEST(empty_reports_nonempty_queue_not_empty)
|
||||||
|
{
|
||||||
|
queue_add(TestQ, &item1);
|
||||||
|
ASSERT_EQ_INT(!!queue_empty(TestQ), 0);
|
||||||
|
}
|
@ -2,8 +2,7 @@
|
|||||||
#include <queue.h>
|
#include <queue.h>
|
||||||
|
|
||||||
#define READYQ readyQ, readyQ_next, struct thread
|
#define READYQ readyQ, readyQ_next, struct thread
|
||||||
QUEUE_DECL(READYQ);
|
QUEUE_DECLARE(READYQ);
|
||||||
QUEUE_HEAD(READYQ);
|
|
||||||
|
|
||||||
void ready(struct thread *th);
|
void ready(struct thread *th);
|
||||||
struct thread *scheduler_next();
|
struct thread *scheduler_next();
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
#include <queue.h>
|
#include <queue.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
|
|
||||||
QUEUE_HEAD_EMPTY(READYQ);
|
QUEUE_DEFINE(READYQ);
|
||||||
|
|
||||||
void ready(struct thread *th)
|
void ready(struct thread *th)
|
||||||
{
|
{
|
||||||
QUEUE_ADD(READYQ, th);
|
queue_add(READYQ, th);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread *scheduler_next()
|
struct thread *scheduler_next()
|
||||||
{
|
{
|
||||||
struct thread *th = QUEUE_PEEK(READYQ);
|
struct thread *th = queue_peek(READYQ);
|
||||||
QUEUE_DROP(READYQ);
|
queue_drop(READYQ);
|
||||||
return th;
|
return th;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user