ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | LICENSE

beamformer_work_queue.c (1558B)


      1 /* See LICENSE for license details. */
      2 #include "beamformer_work_queue.h"
      3 
      4 static BeamformWork *
      5 beamform_work_queue_pop(BeamformWorkQueue *q)
      6 {
      7 	BeamformWork *result = 0;
      8 
      9 	static_assert(ISPOWEROF2(ARRAY_COUNT(q->work_items)), "queue capacity must be a power of 2");
     10 	u64 val  = atomic_load(&q->queue);
     11 	u64 mask = ARRAY_COUNT(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 static void
     22 beamform_work_queue_pop_commit(BeamformWorkQueue *q)
     23 {
     24 	atomic_add(&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(ARRAY_COUNT(q->work_items)), "queue capacity must be a power of 2");
     32 	u64 val  = atomic_load(&q->queue);
     33 	u64 mask = ARRAY_COUNT(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(&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(&q->queue, 1);
     52 }
     53 
     54 static b32
     55 try_wait_sync(i32 *sync, i32 timeout_ms, os_wait_on_value_fn *os_wait_on_value)
     56 {
     57 	b32 result = 0;
     58 	for (;;) {
     59 		i32 current = atomic_load(sync);
     60 		if (current && atomic_cas(sync, &current, 0)) {
     61 			result = 1;
     62 			break;
     63 		}
     64 		if (!timeout_ms || !os_wait_on_value(sync, 0, timeout_ms))
     65 			break;
     66 	}
     67 	return result;
     68 }