63 lines
2.4 KiB
Markdown
63 lines
2.4 KiB
Markdown
# 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.
|