From 91ff9e51605ecd7c64bbee47c79de889569e3d5f Mon Sep 17 00:00:00 2001 From: ratchet freak Date: Tue, 16 Jun 2026 20:35:39 +0200 Subject: [PATCH] fix crash when wait_barrier_slow is called with a nil barrier other backends will guard against that before calling underlying api. --- src/base/base_threads.c | 82 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/base/base_threads.c b/src/base/base_threads.c index a8c72585c..6c3c7a818 100644 --- a/src/base/base_threads.c +++ b/src/base/base_threads.c @@ -131,64 +131,66 @@ slow_barrier_wait(Barrier barrier) { ProfBeginFunction(); BarrierNode *n = (BarrierNode *)barrier.u64[0]; - U64 threads_left_to_enter = ins_atomic_u64_dec_eval(&n->threads_left_to_enter); - - //- rjf: threads left to enter > 0 => wait - if(threads_left_to_enter > 0) + if(n != 0) { - // rjf: first try a spin loop - B32 done_waiting = 0; - ProfScope("spin loop wait") for(U64 spin_count = 0; spin_count < 10000; spin_count += 1) - { - if(ins_atomic_u64_eval(&n->threads_left_to_leave) != 0) - { - done_waiting = 1; - break; - } - } + U64 threads_left_to_enter = ins_atomic_u64_dec_eval(&n->threads_left_to_enter); - // rjf: not done waiting -> need to do slow wait on condition variable - if(!done_waiting) ProfScope("slow wait") + //- rjf: threads left to enter > 0 => wait + if(threads_left_to_enter > 0) { - RWMutexScope(n->rw_mutex, 0) for(;;) + // rjf: first try a spin loop + B32 done_waiting = 0; + ProfScope("spin loop wait") for(U64 spin_count = 0; spin_count < 10000; spin_count += 1) { if(ins_atomic_u64_eval(&n->threads_left_to_leave) != 0) { + done_waiting = 1; break; } - cond_var_wait_rw(n->cv, n->rw_mutex, 0, max_U64); + } + + // rjf: not done waiting -> need to do slow wait on condition variable + if(!done_waiting) ProfScope("slow wait") + { + RWMutexScope(n->rw_mutex, 0) for(;;) + { + if(ins_atomic_u64_eval(&n->threads_left_to_leave) != 0) + { + break; + } + cond_var_wait_rw(n->cv, n->rw_mutex, 0, max_U64); + } + } + + // rjf: decrement leave counter + if(ins_atomic_u64_dec_eval(&n->threads_left_to_leave) > 0) + { + ProfScope("signal") cond_var_signal(n->cv); } } - // rjf: decrement leave counter - if(ins_atomic_u64_dec_eval(&n->threads_left_to_leave) > 0) + //- rjf: threads left to enter == 0 -> last thread, wakeup + else { + ins_atomic_u64_eval_assign(&n->threads_left_to_enter, n->count); + ProfScope("wake up") RWMutexScope(n->rw_mutex, 1) + { + ins_atomic_u64_eval_assign(&n->threads_left_to_leave, n->count-1); + } ProfScope("signal") cond_var_signal(n->cv); } - } - - //- rjf: threads left to enter == 0 -> last thread, wakeup - else - { - ins_atomic_u64_eval_assign(&n->threads_left_to_enter, n->count); - ProfScope("wake up") RWMutexScope(n->rw_mutex, 1) - { - ins_atomic_u64_eval_assign(&n->threads_left_to_leave, n->count-1); - } - ProfScope("signal") cond_var_signal(n->cv); - } - - //- rjf: wait for threads left to leave == 0 - ProfScope("wait for threads to leave") - { - for(U64 spin_count = 0;; spin_count += 1) + + //- rjf: wait for threads left to leave == 0 + ProfScope("wait for threads to leave") { - if(ins_atomic_u64_eval(&n->threads_left_to_leave) == 0) + for(U64 spin_count = 0;; spin_count += 1) { - break; + if(ins_atomic_u64_eval(&n->threads_left_to_leave) == 0) + { + break; + } } } } - ProfEnd(); }