Worked examples — RTOS concepts — task, scheduler, preemption, context switch
The scenario matrix
Think of a scheduling situation as a set of inputs: how many tasks, what priorities, who is Ready, and how expensive a switch is. Each "cell" below is a distinct class of behaviour the scheduler can show. We cover them all.
| Cell | Case class | What is special about it | Example |
|---|---|---|---|
| C1 | Higher-priority arrival | preemption fires mid-execution | Ex 1 |
| C2 | Equal priority (tie) | no preemption — round-robin instead | Ex 2 |
| C3 | Lower-priority arrival | preemption does not fire | Ex 3 |
| C4 | Degenerate: nothing Ready | scheduler must run the idle task | Ex 4 |
| C5 | Overhead — normal regime | small | Ex 5 |
| C6 | Overhead — limiting regime | , system chokes | Ex 6 |
| C7 | Response time bound | highest-priority latency | Ex 7 |
| C8 | Real-world word problem | motor + WiFi + sensor, does it meet deadlines? | Ex 8 |
| C9 | Exam twist | busy-wait vs block changes the answer | Ex 9 |

Example 1 — Higher-priority arrival (cell C1)
Forecast: guess before reading — does B wait for A to finish, or does A get paused instantly?
- At ms the ISR marks B as Ready. Why this step? Readiness is the entry ticket — only now does B even compete for the CPU.
- Scheduler re-evaluates: highest-priority Ready task? B has priority
3> A's1. Why this step? The fixed-priority preemptive rule says always run the highest-priority Ready task — it must re-check the instant anything becomes Ready. - Preempt A → context switch → B runs. A's registers are saved to A's stack, its SP stored in A's TCB; B's SP loaded, its registers restored. Why this step? Preemption means A is paused without its cooperation; the TCB holds the handle to A's frozen state.
- When B blocks (waits for next event), A resumes. Why this step? A is again the highest-priority Ready task, so the scheduler restores it exactly where it was frozen at step 3.
Verify: priority comparison ⇒ preempt. Consistent with the rule "higher priority Ready ⇒ run now." B never waits for A's loop to finish. ✓
Example 2 — Equal priority, a tie (cell C2)
Forecast: same priority — does the newer task shove out the older one?
- Compare priorities:
2vs2— equal. Why this step? Preemption is strictly priority-driven: it requires the newcomer to be higher, not equal. - No preemption occurs. Why this step? An equal-priority task has no claim to interrupt; forcing a switch here would just burn overhead for no urgency gain.
- At the next tick, the scheduler time-slices: C is switched out, D runs. Why this step? Equal-priority tasks share the CPU by round-robin at tick boundaries — fair turns, not preemption.
- On the tick after that, D→C again, and so on. Why this step? Round-robin cycles the equal-priority Ready set one slice each.
Verify: switches happen only at tick boundaries, spaced by one tick period. With a tick that is one switch every between C and D — not instantaneous like C1. ✓ (This is the "equal priority can preempt" mistake, corrected.)
Example 3 — Lower-priority arrival (cell C3)
Forecast: a new task became Ready — must the scheduler switch?
- Compare: F's
1vs E's4. F is lower. Why this step? Same rule, opposite outcome — the comparison decides everything. - E keeps the CPU; F goes to the Ready queue and waits. Why this step? Nothing higher-priority is Ready, so there is no reason to switch. A switch here would be pure waste.
- F runs only when E blocks or finishes. Why this step? F becomes the highest-priority Ready task only after E leaves the Running state.
Verify: ⇒ no preemption. Zero context switches caused by F's arrival. ✓
Example 4 — Degenerate: nothing Ready (cell C4)
Forecast: can the CPU run nothing? What fills the gap?
- Scheduler searches for the highest-priority Ready task — finds none. Why this step? The Ready set is empty, but a CPU must always execute some instruction stream.
- The RTOS runs the built-in idle task (lowest priority, always Ready). Why this step? It is a guaranteed fallback so the scheduler's "pick highest Ready" never fails; the idle task typically issues a
WFI(wait-for-interrupt) to save power. - The next event (ISR) unblocks a real task → scheduler preempts idle instantly. Why this step? Idle is lowest priority, so any Ready task outranks it — collapsing back to cell C1.
Verify: Ready set ⇒ idle runs; idle priority is below every task, so it is preempted by the first arrival. No deadlock, no crash. ✓
Example 5 — Overhead, normal regime (cell C5)
Forecast: guess the percentage before computing.
- Use the overhead model . Why this step? In one second there are ticks; each may force one switch costing seconds, so wasted time out of .
- Substitute: . Why this step? Convert so units cancel: = dimensionless.
- As a percent: . Why this step? Multiply by 100 to express the pure fraction as a percentage.
Verify: dimensionless result in — sane. overhead is negligible. ✓

Example 6 — Overhead, limiting regime (cell C6)
Forecast: does a faster tick make the system more real-time? Guess the two percentages.
- At : . Why this step? Same model — but now switching alone eats a fifth of the CPU before any real work.
- At : . Why this step? This is the limiting case: the product , meaning the CPU spends all its time switching and none running tasks — total collapse.
- Interpret the limit. For we need . Why this step? Beyond this the model gives , which is physically impossible — it signals the CPU can't even keep up with its own switching. Keep tick modest (–).
Verify: at , exactly. Faster tick ⇒ worse, not better — refutes the "higher tick = more real-time" myth. ✓ See Rate Monotonic Scheduling for why event-driven preemption already gives instant response without a fast tick.
Example 7 — Response-time bound (cell C7)
Forecast: can anything else delay the highest-priority task?
- Write the bound . Why this step? Because G is highest priority, only two things can delay it: finishing the triggering ISR () and one switch into G (). No task can block the top task (ignoring priority inversion).
- Substitute: . Why this step? Add the two independent delays; both are pure time so they sum directly.
Verify: is far below a typical deadline ⇒ G comfortably meets it. Units: . ✓ Details of in Interrupts and ISR latency.
Example 8 — Real-world word problem (cell C8)
Forecast: WiFi is busy — will the motor be stuck behind it?
- Encoder ISR fires → Motor becomes Ready. Why this step? Only a Ready task competes; the ISR is the trigger.
- Motor priority
5> running WiFi priority1⇒ preempt WiFi (cell C1 pattern). Why this step? WiFi's long loop does not protect it — preemption is forcible. - Response time . Why this step? Motor is the highest priority, so use the C7 bound.
- Compare to deadline: . Why this step? Convert the deadline to so both are in ; the margin is huge.
Verify: ⇒ deadline met with ~333× margin. WiFi's length is irrelevant because preemption is instant. ✓ (If WiFi held a mutex the Motor needed, we'd hit priority inversion — a different chapter.)
Example 9 — Exam twist: busy-wait vs block (cell C9)
Forecast: in which design does B get to run during the 5 ms wait?
- Design X — busy-wait. A stays Running the whole , spinning. Why this step? A never leaves the Running state, so it remains the highest-priority Ready task and hogs the CPU.
- B's useful of work is starved. Wasted useful capacity . Why this step? B is lower priority and A never yields, so B simply cannot run — that work is lost from the 5 ms window.
- Design Y — block.
xQueueReceivemoves A to Blocked. Why this step? A blocking call releases the CPU by leaving the Running state. - Scheduler runs B (now highest-priority Ready) for its ; CPU can idle only the remaining . Why this step? With A Blocked, B is the top Ready task; useful work fills the gap. Idle waste .
Verify: Design X wastes of possible useful work; Design Y wastes only (unavoidable, since B only has 4 ms of work). Blocking recovers . ✓
Recall
Recall Which arrival cases fire preemption?
Only a strictly higher-priority newcomer (C1). Equal (C2) ⇒ round-robin at ticks. Lower (C3) ⇒ nothing happens. Higher priority arrives while lower runs — result? ::: Immediate preemption + context switch. Two equal-priority tasks both Ready — how do they share? ::: Round-robin time-slicing at tick boundaries, not preemption. Every task Blocked — what runs? ::: The idle task (lowest priority, always Ready).
Recall The overhead limit
At what tick frequency does switching consume 100% of the CPU? ::: , since there. Worst-case response of the highest-priority task? ::: .