From 024d772be8df74546add085b70ac04676401c6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sat, 27 Jan 2018 22:06:36 +0100 Subject: [PATCH] Queues using some macro magic --- src/kernel/include/queue.h | 39 ++++++++++++++++++++++++++++++++++ src/kernel/include/scheduler.h | 5 +++++ src/kernel/include/thread.h | 5 +++-- src/kernel/proc/scheduler.c | 21 ++++++------------ 4 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 src/kernel/include/queue.h diff --git a/src/kernel/include/queue.h b/src/kernel/include/queue.h new file mode 100644 index 0000000..bd48111 --- /dev/null +++ b/src/kernel/include/queue.h @@ -0,0 +1,39 @@ +#pragma once + +#define _QUEUE_DECL(queue, entry, type) \ + struct queue{ \ + type *first; \ + type *last; \ + } +#define QUEUE_DECL(...) _QUEUE_DECL(__VA_ARGS__) +#define _QUEUE_HEAD(queue, entry, type) \ + struct queue queue +#define QUEUE_HEAD(...) _QUEUE_HEAD(__VA_ARGS__) +#define QUEUE_HEAD_EMPTY(...) _QUEUE_HEAD(__VA_ARGS__) = {0,0} + +#define _QUEUE_SPOT(queue, entry, type) \ + type *entry +#define QUEUE_SPOT(...) _QUEUE_SPOT(__VA_ARGS__) + +#define _QUEUE_EMPTY(queue, entry, type) \ + (!(queue.last)) +#define QUEUE_EMPTY(...) _QUEUE_EMPTY(__VA_ARGS__) +#define QUEUE_NOT_EMPTY(...) (!(_QUEUE_EMPTY(__VA_ARGS__))) + +#define _QUEUE_ADD(queue, entry, type, item) \ + if(!queue.last) \ + queue.first = item; \ + else \ + queue.last->entry = item; \ + queue.last = item; \ + item->entry = 0; +#define QUEUE_ADD(...) _QUEUE_ADD(__VA_ARGS__) + +#define _QUEUE_DROP(queue, entry, type) \ + if(!(queue.first = queue.first->entry)) \ + queue.last = 0; +#define QUEUE_DROP(...) _QUEUE_DROP(__VA_ARGS__) + +#define _QUEUE_PEEK(queue, entry, type) \ + (queue.first) +#define QUEUE_PEEK(...) _QUEUE_PEEK(__VA_ARGS__) diff --git a/src/kernel/include/scheduler.h b/src/kernel/include/scheduler.h index 6566cd7..888fecb 100644 --- a/src/kernel/include/scheduler.h +++ b/src/kernel/include/scheduler.h @@ -1,4 +1,9 @@ #pragma once +#include + +#define READYQ readyQ, readyQ_next, struct thread +QUEUE_DECL(READYQ); +QUEUE_HEAD(READYQ); void ready(struct thread *th); struct thread *scheduler_next(); diff --git a/src/kernel/include/thread.h b/src/kernel/include/thread.h index d09bed5..bc36d42 100644 --- a/src/kernel/include/thread.h +++ b/src/kernel/include/thread.h @@ -1,13 +1,14 @@ #pragma once +#include +#include #include - struct thread { uintptr_t stack_ptr; uint64_t tid; uint64_t state; - struct thread *next; + QUEUE_SPOT(READYQ); }; #define TCB_OFFSET (PAGE_SIZE - sizeof(struct thread)) diff --git a/src/kernel/proc/scheduler.c b/src/kernel/proc/scheduler.c index c94f454..f4e1395 100644 --- a/src/kernel/proc/scheduler.c +++ b/src/kernel/proc/scheduler.c @@ -1,26 +1,17 @@ +#include +#include #include -struct { - struct thread *first; - struct thread *last; -} readyQ = {0,0}; +QUEUE_HEAD_EMPTY(READYQ); void ready(struct thread *th) { - if(!readyQ.last) - { - th->next = 0; - readyQ.first = readyQ.last = th; - } else { - readyQ.last->next = th; - readyQ.last = th; - } + QUEUE_ADD(READYQ, th); } struct thread *scheduler_next() { - struct thread *th = readyQ.first; - if(!(readyQ.first = th->next)) - readyQ.last = 0; + struct thread *th = QUEUE_PEEK(READYQ); + QUEUE_DROP(READYQ); return th; }