aboutsummaryrefslogtreecommitdiff
path: root/source/queue.c
diff options
context:
space:
mode:
authornodist <kevin.comas.git@gmail.com>2026-09-23 12:32:31 -0400
committernodist <kevin.comas.git@gmail.com>2026-09-23 12:32:31 -0400
commit07af98f3a5a54a8736109ed031d3177508943299 (patch)
tree032427fabed19c59349c51ce842517e6895a33b8 /source/queue.c
parentd93466b950ff760a1dd7fd0c2d8ae72c8f1ee0b5 (diff)
add task queues
Diffstat (limited to 'source/queue.c')
-rw-r--r--source/queue.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/source/queue.c b/source/queue.c
new file mode 100644
index 0000000..519aa1f
--- /dev/null
+++ b/source/queue.c
@@ -0,0 +1,42 @@
+
+#include "kpl.h"
+
+void kpl_task_queue_init(kpl_task_queue *task_queue) {
+ __atomic_store_n(&task_queue->dummy.next, NULL, __ATOMIC_RELAXED);
+ __atomic_store_n(&task_queue->head, &task_queue->dummy, __ATOMIC_RELAXED);
+ task_queue->tail = (kpl_task*) &task_queue->dummy;
+}
+
+void kpl_task_queue_add(kpl_task_queue *task_queue, kpl_task *task) {
+ __atomic_store_n(&task->next, NULL, __ATOMIC_RELAXED);
+ kpl_task *head = __atomic_exchange_n(&task_queue->head, task, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&head->next, task, __ATOMIC_RELEASE);
+}
+
+kpl_task *kpl_task_queue_next(kpl_task_queue *task_queue) {
+ kpl_task *task = NULL;
+ for (;;) {
+ kpl_task *tail = task_queue->tail, *next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE);
+ if (tail == (kpl_task*) &task_queue->dummy) {
+ if (!next)
+ break;
+ tail = task_queue->tail = next;
+ next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE);
+ }
+ if (!next) {
+ kpl_task *head = __atomic_load_n(&task_queue->head, __ATOMIC_ACQUIRE);
+ if (tail != head)
+ continue;
+ kpl_task_queue_add(task_queue, (kpl_task*) &task_queue->dummy);
+ next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE);
+ }
+ if (next) {
+ task_queue->tail = next;
+ task = tail;
+ break;
+ }
+ }
+ if (task)
+ __atomic_store_n(&task->next, NULL, __ATOMIC_RELAXED);
+ return task;
+}