Expand description
Task types, generic future storage, and the task registry.
Tasks are placed in the .rivet_tasks linker section for discovery
by the executor at startup. Each entry is a TaskReg — just the
metadata the executor needs to poll a task. The task’s actual
Future state machine lives in a TaskCell, sized generically
and monomorphized per concrete future type.
§Why not static TASK: TaskCell<F> = ...?
F is the compiler-generated, unnameable type of an async fn’s
Future. Stable Rust cannot name that type in a static declaration
(that requires type_alias_impl_trait, nightly-only). Instead,
TaskCell is generic over a usize byte size, which is
nameable (TaskCell<512>), and the actual read/write of the future
happens inside a generic method (TaskCell::poll::<F>) that the
compiler monomorphizes separately for each task’s concrete F. This
gets real async fn tasks with static, zero-allocation storage on
100% stable Rust.
Structs§
- Task
Cell - Generic, zero-allocation storage for one task’s
Futurestate machine. - TaskId
- The unified identity of a cooperative-tier task:
(priority, index)packed into one u16, used by the waker, executor, timer queue, semaphore, and channel (plan.md [B12] — replaces two ad-hoc encodings(prio << 24) | indexand(prio << 8) | index). - TaskReg
- Registration entry placed in the
.rivet_taskslinker section. The executor walks these to discover all statically-declared tasks.
Constants§
- DEFAULT_
TASK_ SIZE - Default byte size reserved for a task’s future state machine when the
user doesn’t override it with
#[rivet::task(stack = N)]. - MAX_
PRIORITY - Maximum priority level (0 = lowest, 31 = highest).
- MAX_
TASKS - Maximum number of tasks per priority level (RIVET_MAX_COOP_TASKS).
- TASK_
CELL_ ALIGN - Alignment guaranteed for future storage inside a
TaskCell. Covers all primitive/usize/u64-aligned types used in typical embedded futures.TaskCell::pollasserts this at runtime on first use.