Exercises — Priority inversion — problem and solutions (priority inheritance, priority ceiling)
This page belongs to the parent topic. Before you start, make sure you are comfortable with a few words we will lean on:
- A mutex (mutual-exclusion lock) — a token only one task may hold at a time. See Mutexes vs Semaphores.
- A critical section (CS) — the stretch of code a task runs while holding a mutex. Nobody else may enter the same-mutex critical section until the holder releases.
- Preemption — a higher-priority task instantly kicking a lower one off the CPU. See RTOS task states and context switching.
- ==Blocking time == — the total time a high task is forced to wait because a lower task holds a lock needs.
We will also use three protocol names repeatedly, so pin them down now:
Throughout, priority order is (H is most urgent). We write times in milliseconds (ms).
Level 1 — Recognition
Problem 1.1 (L1)
Three ingredients must all be present for priority inversion. From the list below, tick exactly the three that are required:
(a) preemptive priority scheduling, (b) a shared resource guarded by a mutex, (c) a network connection, (d) at least three priority levels, (e) a floating-point unit.
Recall Solution 1.1
The required three are (a), (b), (d).
- (a) Without preemption, a running task can never be shoved aside — no inversion.
- (b) Without a shared mutex there is no lock for a low task to hold hostage.
- (d) You need three levels so a medium task (neither holder nor waiter) can slip in between and cause the unbounded case. (c) and (e) are irrelevant hardware details.
Problem 1.2 (L1)
Match each term to its one-line meaning:
- Ceiling of a resource — 2. Priority inheritance — 3. Bounded inversion — 4. Unbounded inversion.
A. High waits only for a low task's critical section. B. A medium task hogs the CPU while low holds the lock, so the wait has no upper limit. C. The priority of the highest task that will ever lock the resource. D. A blocking low task temporarily borrows the waiter's priority.
Recall Solution 1.2
1↔C, 2↔D, 3↔A, 4↔B. Key sanity check: inheritance (D) is an action taken after a block; ceiling (C) is a static number computed before runtime.
Level 2 — Application
Problem 2.1 (L2)
, share mutex . 's critical section is ms. A medium task (needs no lock) runs for ms. With no protocol, and under the following timing assumptions — (i) has just acquired and executed none of its critical section yet, (ii) becomes ready immediately after acquires , and (iii) becomes ready right after blocks — how long does wait at minimum?
Recall Solution 2.1
Sequence: locks → (assumption ii) preempts immediately, tries , blocks → resumes → (assumption iii) becomes ready, preempts (M outranks L) → runs ms → finishes its remaining CS → releases → runs. Why L's whole ms CS is still pending: by assumption (i), preempted before had run any of its critical section, so when finally steps aside, still owes the entire ms — none of it was consumed earlier. (If had already run, say, ms of CS before arrived, only ms would remain; we take the worst case where all ms is left.) Wait 's run 's remaining critical section ms (at minimum — more M activations make it worse). This is unbounded in principle: replace with any number and the wait grows.
Problem 2.2 (L2)
Same tasks, but now PIP is enabled on . How long is blocked?
Recall Solution 2.2
When blocks on , inherits 's priority. Now outranks , so cannot preempt . finishes its ms critical section, releases , drops back down; runs. 's blocking 's critical section ms. Bounded — independent of 's ms. ✅
Problem 2.3 (L2)
Two mutexes and . is locked at some point by tasks with priorities ; is locked by . Give the ceiling of each mutex.
Recall Solution 2.3
Ceiling = priority of the highest task that ever locks it.
- .
- . Note 's ceiling is only , even though also locks it — the ceiling tracks the highest locker, not the lowest.
Level 3 — Analysis
Problem 3.1 (L3)
Study the timeline in the figure below. Tasks ; and share . No protocol is running. Identify (i) the instant unbounded inversion begins, and (ii) which task is unrelated to yet dominates 's delay.

How to read this figure: three horizontal lanes, one per task, labelled on the left (bottom = L low, middle = M medium, top = H high). Time runs left→right in ms, with dotted vertical guides at events . A blue bar = actively holding/running ; a pink bar on the H lane = blocked (frozen, waiting for ); a pink bar on the M lane = running its unrelated work; a yellow bar = a task finally running normally. The yellow arrow marks the unbounded gap.
Recall Solution 3.1
(i) Unbounded inversion begins at — the moment preempts while still holds . Before , was only waiting for 's critical section (bounded); at the wait becomes hostage to 's runtime. (ii) is unrelated to (needs neither lock) yet its runtime dominates 's delay — that is the signature of the bug. Look at the long pink bar between and : nothing in it touches , yet (blocked, top lane) is frozen the whole time.
Problem 3.2 (L3)
Compare the same three tasks under PIP (figure below). Explain, using the figure, why the medium bar disappears from between 's critical section.

How to read this figure: same three lanes and time axis as before. The dashed yellow vertical line marks the instant is boosted — it jumps from the bottom (L) lane up to the top (H) lane. The hatched blue bar sitting in the top lane is running its critical section while boosted to H's priority. The dotted "release" line marks where frees and drops back down; the yellow bar is finally running, and the pink bar on the M lane is , now pushed to after the release.
Recall Solution 3.2
At the instant blocks on , 's priority is boosted to 's (the dashed yellow line shows jumping to the top lane). While boosted, outranks , so when becomes ready it is not allowed to preempt — waits its turn. Therefore runs its critical section to completion uninterrupted, releases (yellow "release" tick), and instantly drops back to its low lane. Only then can run. The medium bar is pushed to after the release, so it no longer sits inside 's critical section — the unbounded gap is gone.
Problem 3.3 (L3)
Under PIP with nested mutexes: needs (held by ), and needs (held by ). Trace how the priority boosts propagate. This is called chained (transitive) blocking — explain the name.
Recall Solution 3.3
Chain of dependence: .
- blocks on (held by ) → inherits 's priority.
- But is itself blocked on (held by ) → inherits 's (now 's) priority.
- The boost has propagated down the chain to . runs at 's level, finishes CS on , releases it; un-blocks, finishes CS on , releases it; finally runs. "Chained" = 's wait is the sum of 's CS plus 's CS — two critical sections stacked, because the block travelled through a chain of holders. PIP bounds each link but adds them up.
Level 4 — Synthesis
Problem 4.1 (L4)
Design assignment. Tasks . Resources (ceiling ), (ceiling ). Under PIP, can be blocked on and separately, CS lengths ms and ms. Under PCP (Priority Ceiling Protocol), show that is blocked at most once, and give the worst-case blocking under each protocol.
Recall Solution 4.1
Under PIP — walk the timeline to see why the two critical sections sum:
- locks and starts its ms CS. is preempted (say by 's activation), so is stopped inside 's CS.
- Separately, (on an earlier or interleaved run) locks — OR a second lower task holds for ms. Either way there is a ms CS on that will also need.
- starts. It needs first → blocks for the ms until 's holder finishes and releases. That is one block.
- resumes, runs, then later needs → it finds still held → blocks again for the ms until is released. That is a second, separate block. Because PIP has no gate stopping the second lock from ever being taken, both critical sections can independently be "in progress" and each costs a full block, one after the other. Nothing merges them. Hence they add: Under PCP: suppose locks . The system ceiling (the highest ceiling among currently-locked mutexes) becomes . Now if any task tries to lock , its priority must be strictly greater than the system ceiling — impossible, since no task strictly outranks . So the second lock is denied until is free: the situation where both and are simultaneously locked-and-blocking can never form. is blocked by at most one critical section — the longest relevant one: PCP saves ms of worst-case blocking here, and guarantees "at most once".
Problem 4.2 (L4)
Five tasks lock a mutex : their priorities are (bigger = higher). What is ? Under ICPP (Immediate Ceiling Priority Protocol — a task is raised to a lock's ceiling the moment it acquires the lock), to what priority is raised the instant it locks , and can any task preempt while it holds ?
Recall Solution 4.2
(which is ). Under ICPP, the moment locks it is immediately raised to the ceiling . While holding , runs at priority — the top. Can (priority ) preempt it? By our scheduler's tie-breaking rule (stated at the top of the page), preemption requires a strictly higher priority. and boosted- are equal at , so does not preempt: , already running, keeps the CPU. Every other task () has priority , so none can preempt either. Therefore no task can preempt while it holds . runs its critical section to completion, releases , drops back to . This is why ICPP tasks are "never blocked after they start": they either hold the top rank or were stopped at the door.
Level 5 — Mastery
Problem 5.1 (L5)
Response-time flavour. Task has execution time ms and worst-case blocking . Two lower tasks can each block it once under PIP: their relevant critical sections are ms and ms. There is no medium interference in this window. Using the response-time idea (see Schedulability analysis & response-time analysis), the response time of in this simplified window is . Compute under PIP and under PCP.
Recall Solution 5.1
PIP (blocked at most once per lower task → sum): PCP (blocked at most once total → the single longest): PCP tightens the worst case by ms — the tighter bound is exactly what hard real-time WCET/response-time budgets prize.
Problem 5.2 (L5)
Full formula application. Lower tasks and their relevant critical-section lengths (relevant to ) are: ms, ms, ms. (a) Under PIP, worst-case . Compute it. (b) Under PCP, worst-case over the same set. Compute it.
Recall Solution 5.2
First, each lower task's longest relevant CS:
- :
- :
- :
(a) PIP — sum of those maxima: (b) PCP — the single largest critical section across everything: Ratio : PIP's bound is over larger here. As the number of lower tasks grows, PIP's sum grows while PCP's max stays put — that scaling is the deep reason PCP dominates for many nested resources.
Problem 5.3 (L5)
Reasoning synthesis. A colleague proposes: "Just use ICPP everywhere and forget PIP." Give one true advantage and one honest cost of that choice, tying back to the comparison table.
Recall Solution 5.3
Advantage: ICPP gives the tightest blocking bound ("at most once total"), deadlock-freedom, no chained blocking, and low runtime cost (raise-on-lock is one assignment) — a task is never blocked after it starts. Honest cost: ICPP needs static offline analysis — you must know every task that will ever lock every resource to compute ceilings, and any change to the task set forces recomputation. A task also gets boosted the instant it locks (even if nobody would have blocked it), which can slightly delay unrelated higher tasks that weren't going to touch that resource. PIP needs no static analysis and only boosts when a real block occurs — simpler to deploy in a system whose task set changes often.
Quick self-check
Recall Reveal the numeric answers
Prob 2.1 wait ::: ms Prob 2.2 wait ::: ms Prob 2.3 ceilings ::: Prob 4.1 PIP vs PCP ::: ms vs ms Prob 4.2 ceiling / raise ::: and Prob 5.1 PIP vs PCP ::: ms vs ms Prob 5.2 PIP vs PCP ::: ms vs ms