ADR-010 — Cooperative round-robin on EL1
- Status: Accepted
- Date: 2026-09-09
Context
FR-11 requires cooperative or simple round-robin task switching. Roadmap M9 is that path. The heap already exists (ADR-009); paging is an identity map (ADR-008). The kernel runs at EL1 with SPSel = 0 so SP is SP_EL0 (ADR-005).
Options:
- Async/await executor. Extra
Futureinfrastructure for two markers. - Timer preemption. Would steal the M5 CNTP path and needs IRQ-safe yield. Not required to prove FR-11.
- Cooperative yield that saves AAPCS64 callee-saved GPRs on a per-task stack and switches
SP. - SMP / EL0 processes. Out of scope (vision Out list).
The callee-saved layout is not obvious next to the exception frame in ADR-004 (that frame is x0–x30 + ELR/SPSR/ESR on SP_EL1). A yield must not touch the exception stacks.
Decision
- Cooperative only. Tasks call
sched::yield_now(). No timer slice. DAIF.I stays masked during the hello/test probe (M5 still remasks after its own tick). - AAPCS64 callee-saved switch in
context_switch: save/restorex19–x28,x29,x30on the task stack; store SP in the task slot; load the next SP. No SIMD/FP (ADR-003 soft-float). Not the exception context. - Idle slot 0 is
kernel_main/ the test runner on the linker thread stack. Two workers get 8 KiB stacks from the M8 heap (Vec<u8>, not a stack-allocated[u8; N]that would overflowSP_EL0duringBox::new). Identity VA == PA. - Round-robin among
Readyslots. A worker that returns isDone(trampoline). Idle staysReadyso control returns to the caller ofyield_now. Unlock the scheduler mutex beforecontext_switch. - Serial markers
sched: task a,sched: task b, thensched: okafter both SPs land on distinct heap stacks. Fail closed onsched: probe missed. - Not preemptive, not SMP, not EL0, not async. A later preemptive or process ADR is a new file.
Consequences
scripts/qemu-smoke.shrequires the threesched:strings afterheap: ok, then still requires M2–M8 strings.- Two 8 KiB worker stacks come out of the 64 KiB heap. M8
Box/Vecprobes drop before spawn. - Exception / fatal stacks are unchanged. A yield never runs from an IRQ handler.
- This ADR does not claim Raspberry Pi, preemption, or userspace.