std/sync
Channel, wait-group, and atomic primitives for coordinating green tasks and Promise.blocking workers.
from "std/sync" import { Channel, WaitGroup, AtomicI64, AtomicBool }There is no Mutex or RwLock: green tasks never run in parallel, and parallel Promise.blocking workers share state through channels (pass ownership) or atomics (lock-free counters and flags). See Concurrency.
Types
Channel
struct Channel {
_ptr: *u8,
}Bounded FIFO channel for streaming values between green tasks and Promise.blocking workers. Blocks on send when full, blocks on recv when empty.
WaitGroup
struct WaitGroup {
_ptr: *u8,
}Counting barrier — add before spawning, done from each task, wait for the counter to reach zero.
AtomicI64
struct AtomicI64 {
_ptr: *u8,
}Lock-free 64-bit atomic integer. All operations use sequential consistency.
AtomicBool
struct AtomicBool {
_ptr: *u8,
}Lock-free atomic boolean. All operations use sequential consistency.
Channel Methods
Channel.new
fn Channel.new(capacity: i64): Result<Channel>Create a bounded channel with the given capacity.
ch.send
fn send(self: &Channel, val: i64): Result<i32>Send a value into the channel. Blocks if full.
ch.recv
fn recv(self: &Channel): Result<i64>Receive a value from the channel. Blocks if empty.
ch.trySend
fn trySend(self: &Channel, val: i64): boolNon-blocking send. Returns true if sent, false if full.
ch.tryRecv
fn tryRecv(self: &Channel): Option<i64>Non-blocking receive. Returns Option.None if empty.
ch.len
fn len(self: &Channel): i64Current number of items in the channel.
ch.destroy
fn destroy(self: &Channel): voidFree the underlying channel resource.
WaitGroup Methods
WaitGroup.new
fn WaitGroup.new(): WaitGroupCreate a new wait group with a zero counter.
wg.add
fn add(self: &WaitGroup, n: i64): voidAdd n to the counter — call before spawning the tasks it tracks.
wg.done
fn done(self: &WaitGroup): voidDecrement the counter by one — call from each task when it finishes.
wg.wait
fn wait(self: &WaitGroup): voidBlock until the counter reaches zero.
wg.destroy
fn destroy(self: &WaitGroup): voidFree the underlying wait-group resource.
AtomicI64 Methods
AtomicI64.new
fn AtomicI64.new(v: i64): AtomicI64Create an atomic integer with initial value.
a.load
fn load(self: &AtomicI64): i64Atomic read.
a.store
fn store(self: &AtomicI64, v: i64): voidAtomic write.
a.add
fn add(self: &AtomicI64, v: i64): i64Atomic add. Returns old value.
a.sub
fn sub(self: &AtomicI64, v: i64): i64Atomic subtract. Returns old value.
a.cas
fn cas(self: &AtomicI64, expected: i64, desired: i64): i64Compare-and-swap. Returns old value.
a.destroy
fn destroy(self: &AtomicI64): voidFree the atomic resource.
AtomicBool Methods
AtomicBool.new
fn AtomicBool.new(v: bool): AtomicBoolCreate an atomic boolean with initial value.
a.load
fn load(self: &AtomicBool): boolAtomic read.
a.store
fn store(self: &AtomicBool, v: bool): voidAtomic write.
a.swap
fn swap(self: &AtomicBool, v: bool): boolAtomic swap. Returns old value.
a.destroy
fn destroy(self: &AtomicBool): voidFree the atomic resource.
Example: Producer-Consumer
The producer runs on a Promise.blocking worker so it makes progress while main consumes on the channel (a green producer would only run while the scheduler is driven):
from "std/runtime" import { Promise }
from "std/sync" import { Channel }
fn main(): i32 {
var ch = Channel<i64>.new(8)!
let producer = Promise<i64>.blocking(move (): i64 => {
ch.send(10)!
ch.send(20)!
ch.send(30)!
ch.close()
return 0
})
for val in ch {
print(val)
}
producer.await()!
ch.destroy()
print("done")
return 0
}