# K09 — Scheduler facade and scoped kernel guards ## Position - Series: FreeRTOS C++ - Lesson: L08, card K09 - Duration: 30 minutes - Platform: Hazard3 / RV32I, FreeRTOS V11.3.0 - Evidence: kernel state, `xCriticalNesting`, `mstatus.MIE`, ELF assembly ## Outcome After 30 minutes the student can distinguish scheduler suspension from a critical section, choose a static facade versus an RAII guard, and prove that three early-return paths restore the paired kernel state. ## Lesson plan | Time | Mode | Evidence | | --- | --- | --- | | 0–5 | raw API | classify service calls and paired calls | | 5–10 | critical nesting | record 0→1→2→1→0 and MIE transitions | | 10–15 | critical guard | run three early returns; prove depth 0/MIE 1 | | 15–20 | scheduler guard | prove suspended state with interrupts enabled | | 20–25 | nesting/`this_task` | nested guards, current handle, tick and yield | | 25–30 | ABI and repair | no wrapper symbols; repair three-exit function | ## Canonical comparison | Operation | Context switch | Interrupt MIE | Pair | | --- | --- | --- | --- | | `vTaskSuspendAll` | deferred | remains enabled | `xTaskResumeAll` | | `taskENTER_CRITICAL` | prevented | disabled | `taskEXIT_CRITICAL` | Scheduler suspension can nest. The inner guard's destructor decreases the nesting level but the state remains suspended until the outer guard exits. Critical sections also nest; MIE is enabled only when depth returns to zero. ## Student repair Start with a function containing a manual enter/suspend call and three returns. Replace only the pairing mechanism with the appropriate guard. Verify every path at the checkpoint rather than accepting source-level appearance as proof. ## Acceptance - static facade is non-constructible; - both guards are non-copyable/non-movable and restore all three paths; - raw critical values are exactly 0/1/2/1/0 and MIE 1/0/0/0/1; - scheduler suspension leaves MIE enabled; - nested scheduler guard remains suspended after inner destruction; - `this_task::current()` equals the worker handle; - facade and guard calls are inline with no vtable, RTTI or hosted runtime; - target exits with PASS. ## Main traps 1. `Scheduler` is a facade, not a scoped owner. 2. Scheduler suspension is not interrupt masking. 3. Never block while the scheduler is suspended. 4. A task-context critical guard is not an ISR-safe mutex. 5. RAII balances control flow; it does not make an invalid operation valid.