std.sync
locks, condvars, queues, channels, wait groups; every type is #sync share by address; never copy, move or free one while a thread uses it (join first)
pub Mutex :: struct { word: u64,}zero value is unlocked; no init, no destroy; not recursive, not fair
word: OS lock state; all zero bits is the unlocked state
Mutex.lock
Section titled “Mutex.lock”pub lock :: fn(self: *Self)sleeps until free; relocking from the same thread deadlocks
Mutex.try_lock
Section titled “Mutex.try_lock”pub try_lock :: fn(self: *Self) -> booltake it only if free now; true = caller holds it
Mutex.unlock
Section titled “Mutex.unlock”pub unlock :: fn(self: *Self)caller must hold it; unlocking one it does not hold is UB
CondVar
Section titled “CondVar”pub CondVar :: struct { word: u64,}wait() may wake spuriously: loop on the condition with the lock held signal/broadcast work with or without the lock; a signal with no waiter is lost
word: OS state; zero = nobody waiting
CondVar.wait
Section titled “CondVar.wait”pub wait :: fn(self: *Self, m: *Mutex)release m, sleep, retake m; caller holds m, same Mutex for every waiter
CondVar.wait_timeout
Section titled “CondVar.wait_timeout”pub wait_timeout :: fn(self: *Self, m: *Mutex, ms: u32) -> boollike wait(), but false after ms ms (0xFFFFFFFF = never); lock retaken either way
CondVar.signal
Section titled “CondVar.signal”pub signal :: fn(self: *Self)wake one waiter, if any
CondVar.broadcast
Section titled “CondVar.broadcast”pub broadcast :: fn(self: *Self)wake every waiter
pub Queue :: struct($T: type) { mu: Mutex, not_empty: CondVar, not_full: CondVar, buf: []T, head: usize, count: usize, closed: bool,}bounded blocking MPMC FIFO over caller storage; no alloc, nothing to destroy after close(): push false, pop drains then null; free storage only after joining
buf: the caller’s storage; capacity == buf.lenhead: index of the oldest itemcount: items queued
Queue.push
Section titled “Queue.push”pub push :: fn(self: *Self, item: T) -> boolsleeps while full; false if closed or zero capacity (item not added)
Queue.try_push
Section titled “Queue.try_push”pub try_push :: fn(self: *Self, item: T) -> boolpush only if room now; false if full, closed or zero capacity
Queue.pop
Section titled “Queue.pop”pub pop :: fn(self: *Self) -> ?Tpop the oldest, sleeping while empty; null once closed and drained
Queue.try_pop
Section titled “Queue.try_pop”pub try_pop :: fn(self: *Self) -> ?Tpop the oldest if any now; null if empty
Queue.close
Section titled “Queue.close”pub close :: fn(self: *Self)end the queue, wake all blocked producers and consumers; idempotent
Queue.len
Section titled “Queue.len”pub len :: fn(self: *Self) -> usizeitems queued now; a snapshot
Queue.capacity
Section titled “Queue.capacity”pub capacity :: fn(self: *Self) -> usizeQueue.is_closed
Section titled “Queue.is_closed”pub is_closed :: fn(self: *Self) -> boolmake_queue
Section titled “make_queue”pub make_queue :: fn($T: type, storage: []T) -> Queue(T)queue over storage; it must outlive all users and nothing else may touch it
Channel
Section titled “Channel”pub Channel :: struct($T: type) { queue: Queue(T),}Queue with its own storage; share by pointer, don’t move it while threads use it after close(): send gives false, recv drains then null
Channel.send
Section titled “Channel.send”pub send :: fn(self: *Self, item: T) -> boolwaits while full; false if closed
Channel.try_send
Section titled “Channel.try_send”pub try_send :: fn(self: *Self, item: T) -> boolsend if room now; false if full or closed
Channel.recv
Section titled “Channel.recv”pub recv :: fn(self: *Self) -> ?Twaits while empty; null once closed and empty
Channel.try_recv
Section titled “Channel.try_recv”pub try_recv :: fn(self: *Self) -> ?Tnext item if any now, else null
Channel.close
Section titled “Channel.close”pub close :: fn(self: *Self)no more sends; wakes all waiters; idempotent
Channel.len
Section titled “Channel.len”pub len :: fn(self: *Self) -> usizeitems now; a snapshot
Channel.capacity
Section titled “Channel.capacity”pub capacity :: fn(self: *Self) -> usizeChannel.is_closed
Section titled “Channel.is_closed”pub is_closed :: fn(self: *Self) -> boolchannel
Section titled “channel”pub channel :: fn($T: type, a: *Arena, capacity: usize) -> Channel(T)channel of capacity items; storage in a
WaitGroup
Section titled “WaitGroup”pub WaitGroup :: struct { mu: Mutex, cv: CondVar, pending: usize,}add(n) before the tasks start, done() in each, wait() sleeps until all are done
WaitGroup.add
Section titled “WaitGroup.add”pub add :: fn(self: *Self, n: usize)n more tasks to wait for
WaitGroup.done
Section titled “WaitGroup.done”pub done :: fn(self: *Self)one task done; the last one wakes every waiter
WaitGroup.wait
Section titled “WaitGroup.wait”pub wait :: fn(self: *Self)sleep until every added task called done
pub Once :: struct { mu: Mutex, done: u32,}run something exactly once across threads; later callers wait for it to finish
done: 1 once the function has returned
Once.call
Section titled “Once.call”pub call :: fn(self: *Self, f: fn())run f unless already run; every caller returns after f has returned
Once.is_done
Section titled “Once.is_done”pub is_done :: fn(self: *Self) -> boolRwLock
Section titled “RwLock”pub RwLock :: struct { mu: Mutex, readers_go: CondVar, writer_go: CondVar, readers: usize, writer: bool, writers_waiting: usize,}many readers or one writer; a waiting writer blocks new readers; not recursive
readers: threads that hold it sharedwriter: a thread holds it exclusively
RwLock.lock_shared
Section titled “RwLock.lock_shared”pub lock_shared :: fn(self: *Self)RwLock.unlock_shared
Section titled “RwLock.unlock_shared”pub unlock_shared :: fn(self: *Self)RwLock.lock
Section titled “RwLock.lock”pub lock :: fn(self: *Self)RwLock.unlock
Section titled “RwLock.unlock”pub unlock :: fn(self: *Self)Semaphore
Section titled “Semaphore”pub Semaphore :: struct { mu: Mutex, cv: CondVar, permits: usize,}at most n threads at once
Semaphore.acquire
Section titled “Semaphore.acquire”pub acquire :: fn(self: *Self)take a permit, sleeping until one is free
Semaphore.try_acquire
Section titled “Semaphore.try_acquire”pub try_acquire :: fn(self: *Self) -> booltake a permit only if one is free now
Semaphore.release
Section titled “Semaphore.release”pub release :: fn(self: *Self)give a permit back, wake one waiter
semaphore
Section titled “semaphore”pub semaphore :: fn(permits: usize) -> Semaphoresemaphore with permits permits; keep it in place, share by address