tur/barrier
counting barrier: N threads rendezvous, then all proceed.
barrier-wait blocks until the Nth caller arrives; then all N are released together and the barrier resets for the next round. That reuse is the point -- a barrier is for phased work (every worker finishes phase 1 before any starts phase 2), which is what separates it from a one-shot latch.
Built from mutex + condvar rather than pthread_barrier_t, which is an optional POSIX feature that macOS does not ship -- the same reason stdlib/sync.tur hand-rolls its semaphore instead of using sem_t.
The implementation is a sense-reversing barrier: each round bumps a generation counter, and a waiter sleeps until the generation it arrived in is over. Without that counter a thread that races around the loop and re-enters could be released by its OWN round's broadcast, which is the classic way a hand-rolled barrier lets one thread run a phase ahead.
Load it explicitly: (load "stdlib/barrier.tur").
(let [b (barrier-new 3)] ;; ... three threads each call (barrier-wait b) ... (barrier-free b))
Since: 2026-08-20
Barrier
(defopaque Barrier :ptr<void> :linear)
barrier-new
(barrier-new [n :int] :Barrier)
create a barrier that releases every n-th waiter.
| n | number of threads that must rendezvous; must be >= 1 |
A Barrier handle. Free it with barrier-free.
(let [b (barrier-new 3)] (barrier-free b))
Since: 2026-08-20
barrier-wait
(barrier-wait [^borrow b :Barrier] :bool)
block until n threads have arrived, then release them all.
| b | the Barrier to wait on (borrowed) |
true for exactly ONE of the n threads released -- the one whose arrival tripped the barrier -- and false for the rest. Mirrors PTHREAD_BARRIER_SERIAL_THREAD, and is what lets a single thread run the between-phases work (swap buffers, print a summary) with no extra lock.
(if (barrier-wait b) (println "phase done") 0)
Since: 2026-08-20
barrier-free
(barrier-free [b :Barrier] :nil)
destroy the barrier and release its memory.
Every waiter must have been released first: freeing a barrier threads are still parked on destroys the condvar out from under them.
| b | the Barrier to destroy (consumed) |
(barrier-free b)
Since: 2026-08-20
Internal definitions
barrier/autolink-hint-- hoist the TurBarrier layout to file scope.