Skip to content

kernel::mutex

Kernel-side priority-inheritance mutex (plan W3.2, W3.5, W4).

A higher-priority task blocking on a mutex held by a lower-priority owner boosts the owner to the waiter’s priority. On release, the owner’s effective priority is recomputed from the highest-priority waiter across all mutexes it still holds (so multiple held mutexes compose correctly), and ownership transfers to the next waiter.

fn lock(addr: usize) -> bool

Lock addr. Returns true if owned on return (immediately or after blocking and being granted), false if the lock could not even be queued — table full, waiter list full, called from interrupt context, or (see below) called by the task that already owns it (W3.5 — never a silent fake-success, never a silent deadlock).

This is a non-recursive mutex. The naive fix for “owner tries to lock again” would be either (a) hand back success immediately (reentrant), or (b) detect it and fail loudly. We deliberately choose (b): nothing in this codebase’s MutexGuard/unlock bookkeeping is written to support nested ownership (an inner unlock would release the mutex out from under the still-active outer critical section), so silently granting reentrancy would trade one bug (self-deadlock) for a subtler one (early release while the outer caller still thinks it holds the lock). Failing loudly surfaces the misuse instead of hiding it. The previous behavior — falling through to the “held” branch and enqueuing the owner as its own waiter — deadlocked the task forever with no diagnostic at all.

fn unlock(addr: usize)

Unlock addr, transferring ownership to the next waiter (if any) and recomputing the releasing owner’s inherited priority.

Item 2: refuses (logs, and in debug builds panics) if the caller is not the current owner instead of blindly transferring ownership by address. Without this check any task — buggy or malicious — could release a mutex it never held, corrupting whichever task’s critical section was actually relying on holding it.