diff options
| author | nodist <kevin.comas.git@gmail.com> | 2026-09-23 12:32:31 -0400 |
|---|---|---|
| committer | nodist <kevin.comas.git@gmail.com> | 2026-09-23 12:32:31 -0400 |
| commit | 07af98f3a5a54a8736109ed031d3177508943299 (patch) | |
| tree | 032427fabed19c59349c51ce842517e6895a33b8 /source/queue.c | |
| parent | d93466b950ff760a1dd7fd0c2d8ae72c8f1ee0b5 (diff) | |
add task queues
Diffstat (limited to 'source/queue.c')
| -rw-r--r-- | source/queue.c | 42 |
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; +} |
