beamformer_work_queue.c (1624B)
1 /* See LICENSE for license details. */ 2 #include "beamformer_work_queue.h" 3 4 function BeamformWork * 5 beamform_work_queue_pop(BeamformWorkQueue *q) 6 { 7 BeamformWork *result = 0; 8 9 static_assert(ISPOWEROF2(countof(q->work_items)), "queue capacity must be a power of 2"); 10 u64 val = atomic_load_u64(&q->queue); 11 u64 mask = countof(q->work_items) - 1; 12 u32 widx = val & mask; 13 u32 ridx = val >> 32 & mask; 14 15 if (ridx != widx) 16 result = q->work_items + ridx; 17 18 return result; 19 } 20 21 function void 22 beamform_work_queue_pop_commit(BeamformWorkQueue *q) 23 { 24 atomic_add_u64(&q->queue, 0x100000000ULL); 25 } 26 27 DEBUG_EXPORT BEAMFORM_WORK_QUEUE_PUSH_FN(beamform_work_queue_push) 28 { 29 BeamformWork *result = 0; 30 31 static_assert(ISPOWEROF2(countof(q->work_items)), "queue capacity must be a power of 2"); 32 u64 val = atomic_load_u64(&q->queue); 33 u64 mask = countof(q->work_items) - 1; 34 u32 widx = val & mask; 35 u32 ridx = val >> 32 & mask; 36 u32 next = (widx + 1) & mask; 37 38 if (val & 0x80000000) 39 atomic_and_u64(&q->queue, ~0x80000000); 40 41 if (next != ridx) { 42 result = q->work_items + widx; 43 zero_struct(result); 44 } 45 46 return result; 47 } 48 49 DEBUG_EXPORT BEAMFORM_WORK_QUEUE_PUSH_COMMIT_FN(beamform_work_queue_push_commit) 50 { 51 atomic_add_u64(&q->queue, 1); 52 } 53 54 function void 55 post_sync_barrier(SharedMemoryRegion *sm, BeamformerSharedMemoryLockKind lock, i32 *locks, 56 os_shared_memory_region_unlock_fn *os_shared_memory_region_unlock) 57 { 58 /* NOTE(rnp): debug: here it is not a bug to release the lock if it 59 * isn't held but elswhere it is */ 60 DEBUG_DECL(if (locks[lock])) { 61 os_shared_memory_region_unlock(sm, locks, lock); 62 } 63 }