I’m learning std::sync::Barrier in Rust.
According to the documentation of the wait() method:
pub fn wait(&self) -> BarrierWaitResult(snip)
Barriers are re-usable after all threads have rendezvoused once, and can be used continuously.
A single (arbitrary) thread will receive a
BarrierWaitResultthat returnstruefromBarrierWaitResult::is_leader()when returning from this function, and all other threads will receive a result that will returnfalsefromBarrierWaitResult::is_leader().
I have two questions:
-
How is the leader selected?
-
If we reuse a barrier, is the leader selected in the first use always selected as the leader also in the second use? (As far as I tested, this is true.)Edit: the answer is no (playground).
>Solution :
From the implementation of wait():
pub fn wait(&self) -> BarrierWaitResult {
let mut lock = self.lock.lock().unwrap();
let local_gen = lock.generation_id;
lock.count += 1;
if lock.count < self.num_threads {
let _guard =
self.cvar.wait_while(lock, |state| local_gen == state.generation_id).unwrap();
BarrierWaitResult(false)
} else {
lock.count = 0;
lock.generation_id = lock.generation_id.wrapping_add(1);
self.cvar.notify_all();
BarrierWaitResult(true)
}
}
it appears that it keeps a count of all threads. when a given thread rendezvouses, if it is the last thread, it will become the leader (BarrierWaitResult(true)), otherwise it will become not be the leader (BarrierWaitResult(false)).