#pragma once #include #include "pxl8_types.h" #define PXL8_QUEUE_CAPACITY 256 typedef struct pxl8_queue { void* items[PXL8_QUEUE_CAPACITY]; atomic_uint write_idx; atomic_uint read_idx; } pxl8_queue; static inline void pxl8_queue_init(pxl8_queue* q) { atomic_store(&q->write_idx, 0); atomic_store(&q->read_idx, 0); for (u32 i = 0; i < PXL8_QUEUE_CAPACITY; i++) { q->items[i] = NULL; } } static inline bool pxl8_queue_push(pxl8_queue* q, void* item) { u32 w = atomic_load_explicit(&q->write_idx, memory_order_relaxed); u32 next = (w + 1) % PXL8_QUEUE_CAPACITY; if (next == atomic_load_explicit(&q->read_idx, memory_order_acquire)) { return false; } q->items[w] = item; atomic_store_explicit(&q->write_idx, next, memory_order_release); return true; } static inline void* pxl8_queue_pop(pxl8_queue* q) { u32 r = atomic_load_explicit(&q->read_idx, memory_order_relaxed); if (r == atomic_load_explicit(&q->write_idx, memory_order_acquire)) { return NULL; } void* item = q->items[r]; atomic_store_explicit(&q->read_idx, (r + 1) % PXL8_QUEUE_CAPACITY, memory_order_release); return item; } static inline bool pxl8_queue_empty(const pxl8_queue* q) { return atomic_load_explicit(&((pxl8_queue*)q)->read_idx, memory_order_acquire) == atomic_load_explicit(&((pxl8_queue*)q)->write_idx, memory_order_acquire); } static inline u32 pxl8_queue_count(const pxl8_queue* q) { u32 w = atomic_load_explicit(&((pxl8_queue*)q)->write_idx, memory_order_acquire); u32 r = atomic_load_explicit(&((pxl8_queue*)q)->read_idx, memory_order_acquire); return (w >= r) ? (w - r) : (PXL8_QUEUE_CAPACITY - r + w); }