Module sync

Source
Description

Synchronisation primitives — Mutex, RwLock, Atomic, Lazy, Barrier, Condvar, OnceLock, and their guards.

The memory-ordering enum is named MemoryOrdering rather than the spec's Ordering to avoid colliding with core.Ordering. Atomic has a full set of real bodies; Mutex, RwLock, OnceLock, Barrier, and Condvar cover the core operations. Lazy, Condvar .wait, RwLock .try-read / .try-write, and OnceLock .get-or-init remain stubbed pending quotation-dispatch from intrinsics and :dispose runtime wiring.

The guard types should be local so the locality check at .spawn prevents capture, but the checker today rejects local types in return positions. In the meantime guards are plain by-value records; their :dispose impls (lock release on drop) land with the dispose runtime. .lock / .read / .write currently thread the lock handle back alongside the guard — the spec-accurate signature that consumes the lock returns with RAII guards. Only scalar values (Int / Float / Decimal / Bool / Char / Unit) may be stored inside Mutex / RwLock / OnceLock; the intrinsics return an error for cell-typed values. The +Executor effect row is elided from every signature.

Not re-exported by the prelude — use :use :open silo:std.sync ....

Data Types

Records

Atomic

Atomic cell over a word-sized primitive type.

Barrier

Rendezvous point for n participants.

Condvar

Condition variable paired with a Mutex.

Lazy

One-shot initialisation cell.

Mutex

Exclusive lock guarding a value of type val.

MutexGuard

Linear guard that MUST release the underlying lock on drop.

OnceLock

One-shot cell distinct from Lazy.

ReadGuard

Shared read guard.

RwLock

Reader-writer lock guarding a value.

WriteGuard

Exclusive write guard.

Unions

MemoryOrdering

Memory-ordering tag for atomic operations.

Functions

Functions

atomic-new

Construct an Atomic wrapping an initial value.

barrier-new

Construct a Barrier expecting the given participant count.

condvar-new

Construct a fresh Condvar backed by a shared

lazy-new

Construct a Lazy from a nullary quotation.

mutex-new

Construct a Mutex wrapping an initial value.

oncelock-new

Construct an empty OnceLock.

oncelock-set

Set the cell's value if still empty.

rwlock-new

Construct a RwLock wrapping an initial value.

Trait Implementations

impl Atomic for ?850318

.atomic-cas ( (Atomic t) t t MemoryOrdering MemoryOrdering (Atomic t) (Result t t) )

Atomic compare-and-swap. Takes expected, new, success ordering, failure ordering; returns Ok prev on success, Err current on mismatch.

.atomic-fetch-add ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic fetch-add. Returns the atomic plus the previous value.

.atomic-fetch-and ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic fetch-and. Returns the atomic plus the previous value.

.atomic-fetch-or ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic fetch-or. Returns the atomic plus the previous value.

.atomic-fetch-sub ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic fetch-sub. Returns the atomic plus the previous value.

.atomic-fetch-xor ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic fetch-xor. Returns the atomic plus the previous value.

.atomic-load ( (Atomic t) MemoryOrdering (Atomic t) t )

Atomic load. Returns the atomic threaded through plus the current value.

.atomic-store ( (Atomic t) t MemoryOrdering (Atomic t) )

Atomic store. Returns the atomic threaded through.

.atomic-swap ( (Atomic t) t MemoryOrdering (Atomic t) t )

Atomic swap. Returns the atomic threaded through plus the previous value.

impl Lazy for ?850330

.force ( (Lazy val) (Lazy val) val )

Force the lazy — runs the initializer on first call, returns the cached value on every subsequent call. Spec signature carries +Executor; omitted for the partial stub.

impl Mutex for ?850304

.mutex-lock ( (Mutex val) (Mutex val) (MutexGuard val) )

Acquire the underlying Rust mutex transiently, clone the scalar out, release. Diverges from the spec signature by threading the Mutex handle back through — Silo does not yet enforce local/:dispose on MutexGuard, so each .lock call returns both the handle and the guard record for chaining.

.mutex-try-lock ( (Mutex val) (Mutex val) (Option (MutexGuard val)) )

Non-blocking variant of .mutex-lock. Returns None if the underlying Rust mutex is currently held by another holder.

impl OnceLock for ?850335

.get-or-init ( (OnceLock a) [ a ] (OnceLock a) a )

Atomically initialise on first call or return the cached value. Still stubbed — invoking the initializer quotation needs special machine-instruction support that lands with the +Executor effect. Callers that already have an evaluated value can use .oncelock-set below as a manual-seed building block in the meantime.

.oncelock-get ( (OnceLock a) (OnceLock a) (Option a) )

Return Some if the cell has been initialised, None otherwise. Never blocks and never triggers initialisation.

impl RwLock for ?850311

.rwlock-read ( (RwLock val) (RwLock val) (ReadGuard val) )

Acquire shared-read access transiently, clone the scalar, release. Diverges from the spec signature by threading the RwLock handle back through alongside the guard record (see Mutex note above).

.rwlock-write ( (RwLock val) (RwLock val) (WriteGuard val) )

Acquire exclusive write access transiently, clone the scalar, release. Diverges from the spec signature identically to .rwlock-read.

.try-read ( (RwLock val) (Option (ReadGuard val)) )

Non-blocking read. Returns None if a writer is active. Kept as a stub — needs the real Rust try-variant and is not covered by the WP-F1 real MVP.

.try-write ( (RwLock val) (Option (WriteGuard val)) )

Non-blocking write. Returns None if any reader or writer is active. Kept as a stub for the same reason as .try-read.