Expand description
pub, not private like [gc]: task’s ABI constants (PollFn,
POLL_READY, STATE_SLOT_TAG, STATE_SLOT_TEMPS) are not all read by
this crate’s own runtime logic – some exist purely as the documented
contract codegen (Task 5’s async_lower.rs) must reproduce. A private
module would make those pub items unreachable from outside the crate,
which both defeats their purpose and makes rustc’s dead_code lint treat
them as genuinely dead, since nothing inside this crate alone uses them.
A single-threaded cooperative executor.
Single-threaded is a correctness requirement, not a simplification.
The collector keeps its entire heap in a thread_local! (gc’s HEAP),
so an object allocated on one thread lives in that thread’s heap map and
only that thread’s collector can see or free it – gc::add_root and
gc::remove_root are thread_local! for the identical reason (see their
doc comments in gc.rs). A second thread running Nova code would free
objects the first still holds. This executor’s own state (QUEUE,
TASKS, IN_BLOCK_ON below) is therefore thread_local! too, by
construction rather than by convention: there is no API here for a task
to migrate between threads. See ADR 0009.
No wakers: a task that returns POLL_PENDING is re-queued for another
turn unless it staged a park (see [Wait]), in which case it waits in the
park set instead until a deadline or another task’s completion – the
executor’s only two wake sources – moves it back. Both are scheduled by
the executor itself, not registered as an arbitrary callback the awaited
resource invokes, which is what “no wakers” still means once parking
exists. That makes interleaving between ready tasks deterministic by
construction, which is what lets nova_rt_task_block_on’s round-robin
order be pinned by a test rather than merely observed.
Constants§
- FUTURE_
SIZE - The whole future value’s size in bytes, for the allocation that holds it.
- FUTURE_
SLOT_ POLL - The future value’s own layout – the
{ poll_code, state }two-word fat pointer everynova_rt_task_spawn/nova_rt_task_block_onargument points at, the same shapeMakeClosurebuilds for a closure. Named for the same reasonSTATE_SLOT_TAGand friends are:async_lower.rs(Task 5) builds this layout independently and the two ends are kept in step by nothing but these declared offsets. - FUTURE_
SLOT_ STATE - POLL_
PENDING - A
PollFnreturns this when it has not yet produced a value; the executor re-queues the task for another turn. - POLL_
READY - A
PollFnreturns this once it has written the final value to the state object’s output slot (STATE_SLOT_OUTPUT). - STATE_
MIN_ SIZE - The smallest state object any future may have: the tag and output slots
are read and written unconditionally, for every future, including one
whose
async fnreturns unit and has no temps at all. A state object withnMIR temps is(STATE_SLOT_TEMPS + n) * 8bytes, which is never smaller than this. - STATE_
SLOT_ OUTPUT - STATE_
SLOT_ TAG - The state object’s layout, word-indexed: slot
nis at byte offset8 * n.async_lower.rs(Task 5) must build exactly this layout – this executor and every generated poll function address it by raw offset, with no shared Rust type to keep the two ends in sync if one of them drifts. - STATE_
SLOT_ TEMPS - TIMEOUT_
STATUS_ COMPLETED - The inner future completed before the deadline.
- TIMEOUT_
STATUS_ ELAPSED - The deadline passed with the inner future still pending.
Functions§
- nova_
rt_ ⚠task_ block_ on - Drive this thread’s executor to quiescence and return
future’s output. See [run_to_completion] for exactly what “quiescence” means here. - nova_
rt_ ⚠task_ is_ done - Whether the task named by
future’s state object has completed. - nova_
rt_ ⚠task_ join_ future - A fresh
Future<unit>that completes whenfuture’s task does. - nova_
rt_ ⚠task_ release - End the executor’s claim on the task named by
future’s state object. See [release_internal] for why this exists next tonova_rt_task_take_outputrather than instead of it, and why calling it twice is a no-op rather than a diagnostic. - nova_
rt_ task_ sleep_ future_ nanos - A fresh
Future<unit>that parks fornanosnanoseconds, then completes. - nova_
rt_ ⚠task_ spawn - Queue a
{ poll_code, state }future as a new task and return its id. - nova_
rt_ ⚠task_ take_ output - A completed task’s output slot, taken exactly once.
- nova_
rt_ task_ timeout_ future - A fresh
Future<Int>that pollsfutuntil it completes ornanosnanoseconds pass, reporting which happened. - nova_
rt_ task_ yield_ future - A fresh
Future<unit>that pends once and then completes – whatstd/task’syield_nowawaits. - output_
bits - The raw bits a completed task’s output was copied out as, without taking it and without touching any GC root.
Type Aliases§
- PollFn
- The signature every compiled
async fn’s poll function has – both the hand-written ones this module’s tests drive it with, and the onesasync_lower.rs(Task 5) generates. Reads and writesstate’s slots (seeSTATE_SLOT_TAGand friends) and reportsPOLL_PENDINGorPOLL_READY.