Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 42 additions & 40 deletions src/base/base_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}