#include "kpl.h" extern inline void kpl_object_queue_init(kpl_object_queue *object_queue); extern inline void kpl_object_queue_enqueue(kpl_object_queue *object_queue, void *object); void *kpl_object_queue_dequeue(kpl_object_queue *object_queue) { kpl_object *object = NULL; for (;;) { kpl_object *tail = object_queue->tail, *queue_next = __atomic_load_n(&tail->queue_next, __ATOMIC_ACQUIRE); if (tail == (kpl_object*) &object_queue->dummy) { if (!queue_next) break; tail = object_queue->tail = queue_next; queue_next = __atomic_load_n(&tail->queue_next, __ATOMIC_ACQUIRE); } if (!queue_next) { kpl_object *head = __atomic_load_n(&object_queue->head, __ATOMIC_ACQUIRE); if (head != tail) continue; kpl_object_queue_enqueue(object_queue, (kpl_object*) &object_queue->dummy); queue_next = __atomic_load_n(&tail->queue_next, __ATOMIC_ACQUIRE); } if (queue_next) { object_queue->tail = queue_next; object = tail; break; } } if (object) __atomic_store_n(&object->queue_next, NULL, __ATOMIC_RELAXED); return object; }