Skip to content

stdlib.async

Cooperative single-threaded async executor: tasks, futures, timers and scheduling-aware channels.

Generated from v0.60.1. 5 source files, 78 documented symbols.

async.xi

type AsyncExecutor

=== AsyncExecutor === A cooperative single-threaded scheduler: a FIFO-ish ready-queue plus a set of pending timers. Stored 8-byte-per-slot exactly like Vec[LogEntry].

Field Type
ready Vec[fn() -> Unit]
timers Vec[Timer]

fn new() -> AsyncExecutor

Create an executor with empty ready/timer queues.

fn spawn(self: Self, task: fn() -> Unit)

Enqueue a task onto the ready-queue. It runs on the next drain, not now.

fn at(self: Self, deadline: Int, task: fn() -> Unit)

Register a task to become ready once the clock reaches deadline.

fn step(self: Self) -> Bool

Run a single ready task. Returns true if one was run, false if the ready-queue was empty.

fn fire_due_timers(self: Self)

Advance pending timers: sleep until the earliest deadline, then move every timer that is now due onto the ready-queue (keeping the rest pending).

fn run(self: Self)

Drive the scheduler until both the ready-queue and the timer set are empty.

fn block_on(self: Self, task: fn() -> Unit)

Spawn a task then drive to completion.

fn spawn(task: fn() -> Unit)

=== Spawn === Enqueue an async task onto the global executor's ready-queue. NOTE: unlike the old stub, this no longer runs task inline -- it is scheduled and runs when the executor is driven via run/block_on.

fn run()

Drive the global executor until all tasks and timers are complete.

fn block_on(task: fn() -> Unit)

Spawn a task and drive the global executor to completion.

fn delay(ms: Int, task: fn() -> Unit)

Schedule task to become ready after ms milliseconds (real timer).

  • Precondition: ms >= 0

fn sleep_ms(ms: Int)

Cooperative sleep: wait ms milliseconds while still driving other ready tasks, so the single thread keeps making progress during the wait. NOTE: with no coroutine transform this blocks the calling frame; it does not suspend-and-resume it. Use delay for true fire-after-deadline tasks.

type Channel

=== Channel type ===

Field Type
items Vec[T]
closed Bool
cap Int

Invariants: - items.len() <= cap || cap == 0

fn bounded[T](capacity: Int) -> Channel[T]

Bounded channel holding at most capacity values.

  • Precondition: capacity > 0

fn unbounded[T]() -> Channel[T]

Unbounded channel.

fn send[T](self: Self, value: T)

Send a value (blocking when the channel is full).

fn recv[T](self: Self) -> T

Receive a value (blocking until one is available).

fn try_recv[T](self: Self) -> Option[T]

Non-blocking receive; None when the channel is empty.

fn close[T](self: Self)

Close the channel.

fn async_now_ms() -> Int

Returns the current monotonic time in milliseconds. Complexity: O(1). Thread-safe.

fn async_sleep_ms(ms: Int)

Cooperative sleep: waits ms milliseconds while driving other ready tasks. Complexity: O(ms) pump iterations.

fn async_yield_now()

Yields execution to other ready tasks by sleeping for 0ms. Complexity: O(1) pump iteration.

  • Precondition: true

fn async_spawn(f: fn() -> Unit) -> Int

Enqueues a task onto the global executor and returns a task id. Complexity: O(1). Thread-safe: accesses global executor.

fn async_spawn_delayed(ms: Int, f: fn() -> Unit)

Schedules a task to become ready after ms milliseconds. Complexity: O(1). Thread-safe: accesses global executor.

fn async_step_once(exec: &mut AsyncExecutor) -> Bool

Runs one step of the given executor. Returns true if a task was run. Complexity: O(1). Thread-safe if executor is not shared.

fn async_has_pending(exec: &AsyncExecutor) -> Bool

Returns true if the executor has pending tasks or timers. Complexity: O(1). Thread-safe: reads immutable data.

fn async_run_until_idle(exec: &mut AsyncExecutor)

Drains all ready tasks from the executor without advancing timers. Complexity: O(ready_queue_size).

fn async_timer_count(exec: &AsyncExecutor) -> Int

Returns the number of pending timers in the executor. Complexity: O(1). Thread-safe: reads immutable data.



channel.xi

type AsyncChannel

AsyncChannel[T] - an async message queue that yields instead of blocking.

Field Type
items Vec[T]
closed Bool
cap Int
fn async_channel_new[T](capacity: Int) -> AsyncChannel[T]

Create an async channel with the given capacity (0 = unbounded). Params: capacity - maximum queued items, or 0 for unbounded. Returns: a new empty open channel. Complexity: O(1).

fn async_send[T](ch: &mut AsyncChannel[T], item: T) -> Result[Unit, Str]

Enqueue item, yielding on a full channel; error if closed. Params: ch - the channel; item - the value to send. Returns: Ok(()) on success, Err("channel closed") if closed. Complexity: O(1) per poll; yields while the channel is full.

fn async_recv[T](ch: &mut AsyncChannel[T]) -> Option[T]

Dequeue the next item, yielding when empty; None if closed. Params: ch - the channel. Returns: Some(item) in FIFO order, None if closed and drained. Complexity: O(n) shift per pop; yields while empty.

fn async_try_send[T](ch: &mut AsyncChannel[T], item: T) -> Bool

Enqueue without yielding; false if full or closed. Params: ch - the channel; item - the value to send. Returns: true if queued, false if the channel is full or closed. Complexity: O(1). Never yields.

fn async_try_recv[T](ch: &mut AsyncChannel[T]) -> Option[T]

Dequeue without yielding; None if empty or closed. Params: ch - the channel. Returns: Some(item) in FIFO order, None if empty or closed. Complexity: O(n) shift per pop. Never yields.

fn async_channel_close[T](ch: &mut AsyncChannel[T])

Mark the channel closed. Params: ch - the channel. Complexity: O(1).

fn async_channel_len[T](ch: &AsyncChannel[T]) -> Int

Number of items currently queued. Params: ch - the channel. Returns: the queue length. Complexity: O(1).

fn async_select[T](chs: &Vec[AsyncChannel[T]]) -> Option[Int]

Yield until one channel is ready; returns its index. Params: chs - the channels to watch. Returns: Some(index) of the first channel with a queued item, or None if every channel is closed and drained. Complexity: O(n) per poll; yields while no channel is ready.

type Broadcast

Broadcast[T] - a multi-receiver channel where every subscriber sees each item.

Field Type
items Vec[T]
seen Int
closed Bool
cap Int
fn broadcast_new[T](capacity: Int) -> Broadcast[T]

Create a broadcast channel with the given capacity. Params: capacity - maximum buffered items (0 = unbounded). Returns: a new broadcast channel with no unseen items. Complexity: O(1).

fn broadcast_send[T](b: &mut Broadcast[T], item: T)

Enqueue item for every subscriber. Params: b - the broadcast channel; item - the value. Items beyond a bounded capacity are dropped. Complexity: O(1) amortized.

fn broadcast_recv[T](b: &mut Broadcast[T]) -> Option[T]

Receive the next unseen item; None when caught up or closed. Params: b - the broadcast channel. Returns: Some(item) in order, None once every item has been seen. Complexity: O(1).




executor.xi

type TaskTimer

TaskTimer - a task scheduled to become ready at a deadline.

Field Type
deadline Int
task fn() -> Unit
type Executor

Executor - a scheduler owning a ready queue of tasks and pending timers.

Field Type
ready Vec[fn() -> Unit]
timers Vec[TaskTimer]
fn executor_new() -> Executor

Create an empty executor. Returns: an executor with no ready tasks and no timers. Complexity: O(1).

fn executor_spawn(e: &mut Executor, f: fn() -> Unit)

Enqueue a task to run on the next drain. Params: e - the executor; f - the task. Complexity: O(1) amortized.

fn executor_spawn_blocking(e: &mut Executor, f: fn() -> Unit)

Schedule a blocking task outside the executor thread. Params: e - the executor; f - the task. In this cooperative simulation the task joins the ready queue directly. Complexity: O(1) amortized.

fn executor_run(e: &mut Executor)

Drive the executor until the queues are empty. Params: e - the executor. Complexity: O(tasks) executions plus timer sleeps.

fn executor_run_until_idle(e: &mut Executor)

Drain currently ready tasks without advancing timers. Params: e - the executor. Complexity: O(tasks).

fn executor_shutdown(e: &mut Executor)

Stop accepting tasks and release executor resources. Params: e - the executor. Complexity: O(tasks + timers).

fn executor_tasks(e: &Executor) -> Int

The number of queued tasks and timers. Params: e - the executor. Returns: ready tasks plus pending timers. Complexity: O(1).

fn block_on(f: fn() -> Unit) -> Result[Int, Str]

Spawn f and drive a fresh global-style executor to completion. Params: f - the task. Returns: Ok(0) once f and any spawned work complete. Complexity: O(tasks) executions.




io.xi

type Future

Future - an opaque handle to a pending async operation.

Field Type
ready Bool
value Int
data Vec[UInt8]
fn async_read(fd: Int, buf: &mut Vec[UInt8]) -> Future

Read into buf without blocking. Params: fd - the descriptor; buf - the destination buffer. Returns: a ready Future whose value is the number of bytes read. Complexity: O(n) syscall.

fn async_write(fd: Int, data: &Vec[UInt8]) -> Future

Write data without blocking. Params: fd - the descriptor; data - the bytes to write. Returns: a ready Future whose value is the number of bytes written. Complexity: O(n) syscall.

fn async_read_file(path: Str) -> Future

Read an entire file into memory. Params: path - the file path. Returns: a ready Future whose data holds the file bytes. Complexity: O(n) where n is the file size.

fn async_write_file(path: Str, data: &Vec[UInt8]) -> Future

Write an entire file to disk. Params: path - the file path; data - the bytes. Returns: a ready Future whose value is the number of bytes written. Complexity: O(n) where n is the data length.

fn async_accept(listener: Int) -> Future

Accept a connection on the listener socket. Params: listener - the listening socket fd. Returns: a ready Future whose value is the accepted socket fd or -1. Complexity: O(1) blocking syscall.

fn async_connect(fd: Int, addr: Str, port: Int) -> Future

Open a TCP connection. Params: fd - the socket; addr - the host; port - the port. Returns: a ready Future whose value is the connect result (0 = ok). Complexity: O(1) syscall.

fn async_read_line(fd: Int) -> Future

Read one line from the descriptor. Params: fd - the descriptor. Returns: a ready Future whose data holds the line (newline included). Complexity: O(n) where n is the line length.

fn async_read_until(fd: Int, delim: UInt8) -> Future

Read until the delimiter byte. Params: fd - the descriptor; delim - the delimiter byte. Returns: a ready Future whose data holds the bytes up to and including the delimiter. Complexity: O(n) where n is the number of bytes read.




timer.xi

type Timer

Timer - a handle for a single deadline-based timer event.

Field Type
deadline Int
armed Bool
type TimerFuture

TimerFuture - an opaque handle to a pending async operation.

Field Type
ready Bool
deadline Int
type TimerWheel

TimerWheel - a hashed timing wheel for many timers with bounded overhead. The scheduled entries are stored in three parallel vectors (ids, deadlines, tasks) because calling a fn() held in a struct field does not compile on the current toolchain.

Field Type
slots Int
now Int
ids Vec[Int]
deadlines Vec[Int]
tasks Vec[fn() -> Unit]
next_id Int
type Stopwatch

Stopwatch - a monotonic elapsed-time counter.

Field Type
start Int
fn timer_new() -> Timer

Create an inert timer handle. Returns: a timer that is not armed. Complexity: O(1).

fn timer_sleep(ms: Int)

Cooperatively sleep ms milliseconds. Params: ms - the sleep duration (clamped to >= 0). Complexity: O(1) syscall.

fn timer_delay(ms: Int) -> TimerFuture

Schedule a task to become ready after ms milliseconds. Params: ms - the delay in milliseconds. Returns: a TimerFuture whose deadline is ms from now. Complexity: O(1).

fn timer_interval(ms: Int) -> Timer

Create a repeating interval timer. Params: ms - the interval in milliseconds. Returns: an armed timer whose next fire deadline is ms from now. Complexity: O(1). TODO(compiler): BUG 28 #5 -- catalog struct literals drop trailing fields when the first field expression is a var (Timer{deadline: dl; armed: true} reads armed=false under 4e95717e; constant-field literals work). timer_next therefore returns None for interval timers until fixed.

fn timer_next(t: &Timer) -> Option[Int]

The next fire deadline of t, if armed. Params: t - the timer. Returns: Some(deadline in ms) if armed, None otherwise. Complexity: O(1).

fn timer_wheel_new(slots: Int) -> TimerWheel

Create a timing wheel with slots buckets. Params: slots - the number of slots (clamped to >= 1). Returns: an empty wheel with no scheduled timers. Complexity: O(1).

fn timer_wheel_add(tw: &mut TimerWheel, ms: Int, f: fn() -> Unit)

Schedule f to run after ms milliseconds. Params: tw - the wheel; ms - the delay; f - the task. Complexity: O(1) amortized.

fn timer_wheel_tick(tw: &mut TimerWheel)

Advance one slot, firing every due timer. Params: tw - the wheel. Complexity: O(1) plus the cost of due tasks.

fn timer_wheel_cancel(tw: &mut TimerWheel, id: Int)

Remove a scheduled timer by id. Params: tw - the wheel; id - the timer id. Complexity: O(n) where n is the number of scheduled timers.

fn stopwatch_new() -> Stopwatch

Create a stopwatch started now. Returns: a stopwatch whose elapsed time is zero at creation. Complexity: O(1).

fn stopwatch_elapsed_ms(s: Stopwatch) -> Int

Milliseconds since the stopwatch started. Params: s - the stopwatch. Returns: the elapsed wall-clock milliseconds. Complexity: O(1).

fn stopwatch_reset(s: &mut Stopwatch)

Restart the stopwatch from zero. Params: s - the stopwatch. Complexity: O(1).

fn stopwatch_split(s: Stopwatch) -> Int

Read the elapsed time without resetting. Params: s - the stopwatch. Returns: the elapsed wall-clock milliseconds. Complexity: O(1).