Concurrency Guide
June 29, 2026 · View on GitHub
SageLang provides true multicore concurrency with threads, async/await, atomic operations, POSIX semaphores, condition variables, read-write locks, and SMP/hyperthreading detection.
Threads
thread.spawn(proc, args...)— Spawn a new thread running a procedure with pre-evaluated argumentsthread.join(t)— Wait for thread completion and return its resultthread.mutex()— Create a mutex for synchronizationthread.lock(m)/thread.unlock(m)— Lock and unlock mutexesthread.sleep(ms)— Sleep for millisecondsthread.id()— Get current thread identifier- GC thread safety — Garbage collector protected with pthread mutex
Async / Await
async proc name():— Declares an asynchronous procedure (setsis_asyncflag); calling it automatically spawns a background thread viathread_spawn_nativeawait future— Joins the async thread and returns the result- AST nodes:
STMT_ASYNC_PROC,EXPR_AWAIT
async proc compute(x):
return x * x
let future = compute(42)
print await future # 1764
Atomics (true __atomic builtins)
atomic_new(init)— Create an atomic valueatomic_load(a)— Atomically readatomic_store(a, v)— Atomically writeatomic_add(a, v)— Atomic addatomic_cas(a, exp, des)— Compare-and-swapatomic_exchange(a, v)— Atomic exchange
Additional C-level operations: sub, fetch_and, fetch_or. Safe for
concurrent access across cores.
Semaphores (POSIX)
sem_new(permits)— Create a counting semaphoresem_wait(s)— Blocking wait (decrement)sem_post(s)— Post (increment)sem_trywait(s)— Non-blocking wait
Condition Variables
sage_cond_wait(), sage_cond_signal(), sage_cond_broadcast() — C-level
pthread_cond_t primitives.
Read-Write Locks
sage_rwlock_rdlock(), sage_rwlock_wrlock() — concurrent readers, exclusive
writers. Also tryrdlock / trywrlock / unlock.
SMP / Multicore Detection
cpu_count()— Logical CPU countcpu_physical_cores()— Physical corescpu_has_hyperthreading()— SMT detectionthread_set_affinity(core_id)— Pin a thread to a corethread_get_core()— Current core index
The lib/os/smp.sage library provides higher-level multicore helpers:
- Topology:
topology(),cpu_count(),physical_cores(),has_hyperthreading() - Affinity:
pin_to_core(id),current_core() - Per-CPU data:
per_cpu_array(),per_cpu_get(),per_cpu_set() - Work distribution:
parallel_for_cores(items, fn),on_all_cores(fn) - IPI simulation:
send_to_core(core_id, fn)
Thread Safety
The GC mutex protects allocation and collection; environment list operations are mutex-protected. All concurrency primitives have RP2040 stubs for cross-platform compatibility.
Standard Library Concurrency Modules
The lib/std/ library also provides pure-Sage concurrency building blocks:
atomic (atomic ints/flags/spinlocks), rwlock, condvar (barriers/latches/
semaphores), channel (Go-style buffered channels), and threadpool
(work queue / parallel map / futures).