summaryrefslogtreecommitdiff
path: root/src/kernel/queue.h
diff options
context:
space:
mode:
authordzwdz2024-07-14 23:20:35 +0200
committerdzwdz2024-07-15 00:12:54 +0200
commitfb7949549435e735acef3674b10f429fa4c4789e (patch)
treee9822bd08a806897e042c48a6279db5ad14cc175 /src/kernel/queue.h
parentad99cc4245dd2dfda37e40146609e09cf2e409c6 (diff)
kernel: new queue abstraction
The postqueue functions remain as-is, as that's a more "specialized" interface. They're mostly wrappers around queue.h, though.
Diffstat (limited to 'src/kernel/queue.h')
-rw-r--r--src/kernel/queue.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/kernel/queue.h b/src/kernel/queue.h
new file mode 100644
index 0000000..896824f
--- /dev/null
+++ b/src/kernel/queue.h
@@ -0,0 +1,37 @@
+/* documented in queue(9) */
+#include <kernel/panic.h>
+
+/* struct QueueNode {
+ * ...
+ * struct QueueNode *name_next;
+ * ...
+ * }
+ * struct QueueHead {
+ * struct QueueNode *head, **slot;
+ * }
+ */
+
+#define QUEUE_INIT(q) do { \
+ (q)->head = NULL; \
+ (q)->slot = &(q)->head; \
+} while(0)
+
+#define QUEUE_APPEND(q, name, el) do { \
+ assert((el)->name##_next == NULL); \
+ assert((q)->slot != NULL); \
+ assert(*(q)->slot == NULL); \
+ *(q)->slot = (el); \
+ (q)->slot = &(el)->name##_next; \
+} while(0)
+
+#define QUEUE_POP(q, name) ({ \
+ typeof((q)->head) __q_el = (q)->head; \
+ if (__q_el) { \
+ (q)->head = __q_el->name##_next; \
+ __q_el->name##_next = NULL; \
+ if ((q)->slot == &__q_el->name##_next) { \
+ (q)->slot = &(q)->head; \
+ } \
+ } \
+ __q_el; \
+})