Kernel: Mutex
Overview
The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader ksync (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects. The design uses a single-word owner field (m_bits) combining owner thread pointer with flags (lock bit, queue bit). Contention spins briefly then sleeps on a circular doubly-linked waiter queue. Priority inheritance propagates up blocked chains. The implementation supports debugging/metering via optional info structures and integrates with spinlocks, bitlocks, mrlocks, and semaphores through sv_t wrappers.
Key Functions
Initialization (kmutei_init) Creates zones for mutex_t and sv_t structures. Initializes hash buckets for optional wchan info (debug/metering). Allocation (mutex_alloc / init_mutex) Zone-allocates mutex_t, clears bits, optionally allocates metering/info structure. Deallocation (mutex_destroy / mutex_dealloc) Frees info structure, zone-frees mutex. Core Operations
mutex_trylock: Atomic compare-and-swap to set owner; updates metering. mutex_lock: Trylock → on miss, queue and sleep with priority inheritance probing. mutex_unlock: Clears owner; if waiters, wakes highest-priority waiter (single thread). mutex_wait: Queues thread, handles inheritance, blocks (non-breakable). mutex_wake: Dequeues highest-priority waiter, transfers ownership, updates metering.
Priority Inheritance
resource_raise_owner_pri: Boosts owner priority to waiter’s. resource_test_owner_pri: Detects inversion, raises or spins/yields. drop_inheritance: Restores base priority on unlock. Supports chained inheritance via k_inherit pointer.
Waiter Queue Management
Circular doubly-linked list in m_queue. Queued in approximate priority order (mutex_queue). Single waiter woken on unlock (mutex_wake).
Synchronization Variables (sv_t) General-purpose wait queue supporting:
FIFO, LIFO, priority, keyed ordering. Signal (wake one), broadcast (wake all), bounded broadcast. Timed waits, signal-breakable waits. Integration with mutex/spin/bit/mrlock/sema release.
Undocumented or IRIX-Specific Interfaces and Behaviors
Critical Structures
mutex_t: __psunsigned_t m_bits — owner thread pointer + flags (low bit lock, next bit queue). kthread_t *m_queue — circular waiter list head. Optional m_info pointer for metering/wchan info.
sv_t: __psunsigned_t sv_queue — waiter pointer + lock bit + type (FIFO/LIFO/PRIO/KEYED). Optional sv_info for metering.
Flags/macros: MUTEX_LOCKBIT, MUTEX_QUEUEBIT SV_LOCK, SV_TYPE masks KT_WMUTEX, KT_WSV thread sleep flags
Priority Inheritance Details
Aggressive: propagates through chains, handles indirect waits. Temporary priority boost with KT_PS flag. Supports real-time and timeshare scheduling.
Metering and Debug (SEMAMETER/SEMAINFO)
Optional per-object statistics (lock attempts, hold/wait times, contention). Hash bucket lists for idbg scanning.
sv_t Flexibility
Unified queue for multiple lock types via wrapper functions. Supports bounded broadcast (wakes only original waiter set). Threshold wake (sv_threshold).
Similarities to illumos and BSD Kernel Implementations
illumos (Solaris-derived) Strong similarity due to shared SVR4 heritage:
Adaptive mutexes with priority inheritance (similar owner word, waiter lists). mutex_enter, mutex_tryenter, mutex_exit. Turnstiles for sleeping/waiting (similar to sv_t but more integrated). CVs and semaphores separate but similar. Metering via kstat or dtrace.
Porting: illumos adaptive mutex closest match. Differences in turnstile priority blocking vs IRIX explicit inheritance chains.