Module sync/barrier
Reusable N-party barrier — the generation model, the same one Rust's
std::sync::Barrier and POSIX pthread_barrier_t carry.
Every thread that calls wait() blocks until parties threads have called
it. All of them are then released together, the barrier resets, and it can
be used again for the next round. Exactly one of the released threads —
the last to arrive, which is the one that tripped the barrier — gets true
back from wait(), so a caller can nominate a single thread to do the
between-rounds bookkeeping (Rust spells this BarrierWaitResult::is_leader).
{ Barrier } :: import "std/sync/barrier";
{ Thread } :: import "std/thread";
b := Barrier.new(i32(3));
t1 := Thread(unit).spawn((io) => { b.wait(); });
t2 := Thread(unit).spawn((io) => { b.wait(); });
b.wait(); // the third party — all three proceed from here
t1.join();
t2.join();
Stability
stable — new, wait, parties, generation and waiting follow the
generation model std::sync::Barrier and pthread_barrier_t both carry,
and wait's single true is Rust's BarrierWaitResult::is_leader without
the wrapper struct. generation and waiting are observability, so they
are honest about being a SNAPSHOT: by the time you read either, another
party may have arrived.
Types
Reusable barrier built on Mutex and Cond.
Uses atomic reference counting for safe cross-thread sharing.
_generation is what makes the barrier reusable and correct. A waiter
samples it on arrival and sleeps until it CHANGES, rather than sleeping
until _count returns to zero: a thread from the round that just tripped
can re-enter the barrier and bump _count before a slower sibling of the
previous round has been scheduled, so _count alone cannot tell that
sibling whether its own round is over. The generation can, because it only
ever moves forward.
Fields
| Name | Type | Description |
|---|---|---|
_parties | i32 | |
_count | i32 | |
_generation | i64 | |
_mutex | Mutex(bool) | |
_cv | Cond |
impl(Barrier, ...)
new : (Barrier) fn(parties : i32) -> BarrierCreate a barrier that trips once parties threads are waiting on it.
parties <= 1 yields a barrier that never blocks: the single arriving
thread trips it immediately and is its own leader.
Parameters
| Name | Type | Notes | Description |
|---|---|---|---|
parties | i32 | The number of threads this barrier trips on. Fixed at construction. |
Returns: Barrier
wait : (Barrier) fn(self : Barrier) -> boolBlock until parties threads have called wait(). Returns true in
exactly one of them per generation — the thread that tripped the barrier.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Barrier |
Returns: bool
parties : (Barrier) fn(self : Barrier) -> i32The number of threads this barrier trips on. Fixed at construction.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Barrier |
Returns: i32
generation : (Barrier) fn(self : Barrier) -> i64How many times the barrier has tripped so far — the round a caller arriving now would join.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Barrier |
Returns: i64
waiting : (Barrier) fn(self : Barrier) -> i32How many threads are currently parked in wait() for the round in
progress. Informational only.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Barrier |
Returns: i32