Skip to content

std.thread

OS threads, Scope (joined at block end), Pool (parallel loops)

pub Thread :: struct {
token: i64,
}
pub ok :: fn(self: *Self) -> bool

false if spawn failed

pub join :: fn(self: *Self) -> u32

blocks, returns the exit code (8 bits on linux); don’t reuse after

pub detach :: fn(self: *Self)

no wait; it runs to completion on its own

pub is_running :: fn(self: *Self) -> bool

non-blocking poll

pub spawn :: fn(entry: *void, arg: *void) -> Thread

entry is fn(*void) -> u32 via core::fn_ptr; arg must outlive the thread

pub current_id :: fn() -> u32
pub sleep :: fn(ms: u32)

at least ms ms

pub yield_now :: fn()

scheduler hint, cooperative back-off

pub cpu_count :: fn() -> u32

logical cpus; a sane default thread count

pub ThreadGroup :: struct {
tokens: [64]i64,
count: usize,
}

–– ThreadGroup –– up to MAX_GROUP threads; join_all blocks until all are done

  • tokens: MAX_GROUP slots
pub spawn :: fn(self: *Self, entry: *void, arg: *void)

silently ignored past MAX_GROUP

pub join_all :: fn(self: *Self)

blocks until all are done, then resets for reuse

pub group :: fn() -> ThreadGroup
pub Scope :: struct {
arena: Arena,
tasks: ?*ScopeTask,
spawned: usize,
}

–– Scope –– zone kind; joined on every exit from the block, so captured locals stay valid

  • tasks: the spawned closures, the newest first
pub make :: fn() -> Scope

reserves nothing until the first spawn

pub spawn :: fn(self: *Self, f: fn())

runs f inline if no thread starts; captures are shared, checked by #spawns

pub join :: fn(self: *Self)

waits for all spawned so far; zone end does it anyway, spawning after is fine

pub count :: fn(self: *Self) -> usize
pub alloc_bytes :: fn(self: *Self, n: usize) -> []u8

zone protocol: closure memory

pub deinit :: fn(self: *Self)

zone end: join all, then free

pub Pool :: struct {
arena: Arena,
mu: Mutex,
wake: CondVar,
finished: CondVar,
workers: []i64,
started: bool,
stopping: bool,
job: fn,
round: u64,
next: usize,
end: usize,
chunk: usize,
working: usize,
}

–– Pool –– zone kind for parallel loops; cores-1 workers plus the caller, started at the first job

  • wake: a job is posted, or the pool stops
  • finished: the last worker is done with the job
  • workers: their threads, started at the first job
  • round: jobs posted so far
  • next: the next index to take
  • working: workers not yet done with the job
pub make :: fn() -> Pool

no thread starts until the first job

pub range :: fn(self: *Self, start: usize, end: usize, f: fn(usize))

f(i) for i in start..end across the pool; returns when every call is done

pub each :: fn($T: type, self: *Self, items: borrow []T, f: fn(*T))

f(&items[i]) across the pool; each call writes only its own item

pub threads :: fn(self: *Self) -> usize

workers + the caller

pub alloc_bytes :: fn(self: *Self, n: usize) -> []u8

zone protocol: closure memory

pub deinit :: fn(self: *Self)

zone end: stop the workers, then free

pub parallel :: fn(start: usize, end: usize, f: fn(usize))

one loop on a throwaway pool (a thread start per core); reuse a Pool for many loops