Queues using some macro magic

This commit is contained in:
Thomas Lovén 2018-01-27 22:06:36 +01:00
parent fd0ca6f617
commit 024d772be8
4 changed files with 53 additions and 17 deletions

View File

@ -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__)

View File

@ -1,4 +1,9 @@
#pragma once
#include <queue.h>
#define READYQ readyQ, readyQ_next, struct thread
QUEUE_DECL(READYQ);
QUEUE_HEAD(READYQ);
void ready(struct thread *th);
struct thread *scheduler_next();

View File

@ -1,13 +1,14 @@
#pragma once
#include <queue.h>
#include <scheduler.h>
#include <memory.h>
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))

View File

@ -1,26 +1,17 @@
#include <scheduler.h>
#include <queue.h>
#include <thread.h>
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;
}