← Catalog

RFC-006AcceptedRuntime

Runtime

Depends: RFC-000RFC-001RFC-003

Blocks: RFC-007RFC-008RFC-013

1. Abstract

This RFC specifies the Aura runtime linked into application binaries: tracing GC, M:N task scheduler, async I/O reactor, exception personality support, panic/abort paths, timers, and C ABI FFI bridges. The runtime is shipped as libraries produced by the Rust toolchain and linked by aura build, not installed as a separate end-user package.

Toolchain today (2026-07-16): C runtime stub runtime/aura_rt.c linked by the C backend — println, exception frames (throw/catch object payloads), Array helpers, and GC MVP (aura_gc_alloc + free-all on exit). No M:N scheduler, channels, async I/O, or full concurrent GC yet.

2. Motivation

2.1 Problem statement

A GC + task language needs a coherent runtime ABI for codegen (RFC-004) and stdlib (RFC-007). Single-binary deploy requires the runtime to be linkable and stripable, with documented knobs for servers.

2.2 Why now

Without a runtime contract, compiler lowering and stdlib cannot stabilize.

2.3 Success metrics

MetricTarget
Hello binaryLinks runtime, allocates, prints, exits 0
Tasks100k+ sleeping tasks feasible on commodity hardware (order-of-magnitude goal)
GCCorrect collection under concurrent allocation
FFICall C write / libc subset safely with pins

3. Goals

  • Provide GC, scheduler, I/O, exceptions as linked libraries.
  • Stable runtime ABI for compiler-generated code (versioned).
  • Observability hooks (metrics, tracing) without mandatory heavy agents.
  • Minimal default footprint for CLIs; tunable for servers.

4. Non-goals

  • Distributed runtime / cluster membership.
  • JVM-compatible object model.
  • Hot code reload / dynamic agent attach in v1.
  • Guaranteed hard real-time latency.

5. Prior art & alternatives

RuntimeNotesTake
Go runtimeGC + goroutines + netpollPrimary inspiration
JVMMature GC, heavyComplexity ceiling
.NET Native/AOTSingle-file trendsDeploy inspiration
libuv / tokioReactorsI/O patterns (Rust side may use similar)
WASM runtimesSandboxNot v1 host

6. Design

6.1 Overview

code
┌──────────────────────────────────────────┐
│              Application code            │
├──────────────────────────────────────────┤
│  Stdlib (Aura)                           │
├──────────────────────────────────────────┤
│  Runtime ABI (calls from codegen)        │
│  ┌────────┐ ┌──────────┐ ┌────────────┐  │
│  │  GC    │ │ Scheduler│ │  I/O poll  │  │
│  └────────┘ └──────────┘ └────────────┘  │
│  ┌────────┐ ┌──────────┐ ┌────────────┐  │
│  │Except. │ │  Timers  │ │ FFI / stubs│  │
│  └────────┘ └──────────┘ └────────────┘  │
├──────────────────────────────────────────┤
│  OS: threads, sockets, files, virtual mem│
└──────────────────────────────────────────┘

Runtime components may be implemented in Rust (and/or C for tiny stubs), exposed to LLVM codegen via known symbols (aura_rt_*).

6.2 GC

TopicDirection
ModelTracing GC, precise preferred
ConcurrencyPhased: free-all MVP → precise STW mark-sweep → concurrent later
RootsStack maps / statepoints from LLVM; global roots registry
FinalizationWeak; prefer explicit resource management
TuningEnv/AURA_GC_* or runtime flags: heap size, pacing

Safepoints: compiler inserts polls at back-edges and calls (policy with RFC-004).

6.3 Scheduler

  • M:N tasks on a worker pool (default: CPU count).
  • Work-stealing queues.
  • Cooperative yield at await points; optional preemption via safepoint time slices (open).
  • spawn, join, cancellation propagation for scopes.
  • spawn_blocking for sync OS calls that would stall workers.

6.4 Async I/O

  • Reactor integrates with OS primitives (epoll/kqueue/IOCP).
  • Stdlib net/fs async APIs park tasks rather than blocking workers.
  • Timers: min-heap / time wheel wheel in runtime.

6.5 Exceptions & panics

  • Exceptions are language-level; runtime provides raise/unwind landing pads with LLVM EH.
  • Uncaught exception in main → print diagnostic, exit non-zero.
  • Uncaught in task → surface on join; if detached, log + default handler.
  • Abort path for fatal OOM / corrupted runtime.

6.6 Allocation API (compiler ABI)

Illustrative symbols (names TBD):

code
aura_rt_alloc(size, type_id) -> ptr
aura_rt_alloc_array(elem_size, len, type_id) -> ptr
aura_rt_write_barrier(obj, field, new_value)  // if concurrent GC needs it
aura_rt_safepoint()
aura_rt_throw(exc_ptr) -> !
aura_rt_spawn(fn_ptr, env_ptr)
aura_rt_await(...)

Versioning: AURA_RT_ABI_VERSION checked at startup.

6.7 FFI

  • C ABI extern declarations in Aura (extern "C" fun ...) lowered to LLVM.
  • Libc linking as needed per target.
  • Pin APIs for byte buffers across calls.
  • Callbacks from C into Aura require runtime re-entry rules (documented).

6.8 Startup / shutdown

  1. Runtime init (GC, scheduler, main thread).
  2. Run static initializers (order rules: within package defined; across packages by dependency topo).
  3. Call user main.
  4. Drain tasks or cancel on exit policy.
  5. Flush stdio; GC teardown optional.

6.9 Configuration

KnobExample
WorkersAURA_GOMAXPROCS-like
Heapmax heap, soft limits
Race detectoron/off (dev builds)
Loggingruntime debug log level

6.10 Examples

code
# build links libaura_rt
aura build -o app
./app
AURA_WORKERS=4 AURA_GC_MAX_HEAP=512m ./app

6.11 Error model / edge cases

CaseBehavior
OOMAbort in MVP (optional OutOfMemoryError later)
Stack overflowGuard pages / async state machines reduce risk; hard abort if native overflow
Dead schedulerFatal diagnostic
ABI mismatchFail fast at startup

6.12 Compatibility & migration

  • Runtime ABI major bumps with toolchain major.
  • Older binaries not guaranteed to load newer shared RT (static link default avoids this).

7. Open questions

#QuestionOptionsOwnerStatus
1Exact GC algorithmRuntimeResolved — free-all MVP → precise STW mark-sweep → concurrent later
2Static linking only vs optional dynamic RTstatic defaultDistResolved — static default
3OOM: abort vs throwabort MVPRuntimeResolved
4PreemptionRuntimeResolved — cooperative await + safepoint polls (hybrid with RFC-003)

8. Rationale & trade-offs

Linking the runtime into each binary matches single-file deploy and avoids “install runtime first.” Go-like scheduler matches language concurrency. Implementing RT in Rust aligns with the toolchain monorepo. Cost: larger binaries than freestanding C; mitigated by LTO/strip and feature flags (CLI vs server profiles).

9. Unresolved / future work

  • Continuous profiling integration
  • GC visualization tools
  • Optional arena APIs for buffers
  • Windows IOCP maturity checklist

10. Security & safety considerations

  • Runtime is trusted computing base for all apps.
  • FFI re-entry and callbacks are high-risk; document threat model.
  • Allocator integrity checks in debug.
  • Race detector memory overhead only when enabled.

11. Implementation plan (optional)

PhaseScopeExit criteriaStatus
R0Alloc + print + exitHelloDone (C1 + C3x path)
R1GC MVP single-threadClass heap refsPartial — alloc + free-all (C3x/C3y); not full tracing
R2Scheduler + channelsConcurrent testsDeferred
R3Async net + exceptionsEcho serverExceptions partial (C3c/C3g/C3s); async net deferred

12. References


Changelog

DateAuthorChange
2026-07-16Lock GC/preemption; Status → Accepted
2026-07-16Status → In Review — Review: solid runtime design; GC algo + scheduler still open
2026-07-16Note C runtime MVP status vs full RFC
2026-07-15Initial skeleton
2026-07-15Solid draft: GC, M:N, FFI, ABI sketch
2026-07-15Lock static link default, OOM abort MVP