Skip to main content

Module monitor_wait

Module monitor_wait 

Source
Expand description

Monitor-based wait tier: hardware MONITOR/MWAIT-class waiting between the spin tier and the kernel-park tier.

The wait ladder this slots into:

TierMechanismWait scaleCore while waitingProducer wake cost
spinPAUSE loopnsbusyfree (the store)
monitor (this module)MONITORX/MWAITX (AMD) or UMONITOR/UMWAIT (WAITPKG)us, boundedlight sleep (C0.1)free (the store)
parkfutex / _umtx_op / WaitOnAddressunboundedreleased to the OSone syscall

The monitor tier’s two properties the other tiers lack:

  • The producer’s wake is free. The waiter arms a hardware monitor on the slot’s cache line; ANY store to that line trips it. The producer’s existing state-CAS IS the wake - no syscall on the wake side, unlike every kernel-park mechanism.
  • Monitors are physical-address based (AMD APM / Intel SDM MONITOR semantics), so a store from ANOTHER PROCESS that mapped the same MMF page wakes the waiter. On Windows - where WaitOnAddress is intra-process only - this is the first non-polling cross-process wake the substrate has.

What it is NOT: a park. MWAITX / UMWAIT hold the core in a shallow sleep state with a hardware deadline; the OS cannot schedule other work there. The tier therefore takes a bounded cycle budget and reports false on expiry so the caller escalates to the kernel park.

§Instruction facts (verified against the Linux kernel’s

arch/x86/include/asm/mwait.h and the Intel SDM UMWAIT page)

  • MONITORX: address in rAX, ECX = extensions (0), EDX = hints (0). Both extension registers MUST be zero - nonzero raises #GP, and the Windows x64 ABI happily leaves argument garbage in RCX if the wrapper does not pin it.
  • MWAITX: EAX = hints (0), EBX = max wait “expressed in SW P0 clocks; the software P0 frequency is the same as the TSC frequency”, ECX bit 1 = enable the timer.
  • UMONITOR r64: address operand.
  • UMWAIT r32: register operand = control (bit 0: 1 = C0.1 shallow/fast wake, 0 = C0.2 deeper; other bits #GP); implicit EDX:EAX = ABSOLUTE TSC deadline; wakes on monitored store, deadline, or the OS’s IA32_UMWAIT_CONTROL cap (CF set).
  • Detection: MWAITX = CPUID 0x8000_0001 ECX bit 29 (AMD); WAITPKG = CPUID 7.0 ECX bit 5 (Intel Tiger Lake+ / Sapphire Rapids+, AMD Zen 5+).

Both waits can wake spuriously (interrupts trip monitors), so the loop re-arms until the value changes or the budget expires.

§Tuning

  • SUBETHA_NO_MONITOR_WAIT=1 disables the tier (callers fall straight from spin to park).
  • SUBETHA_MONITOR_WAIT_CYCLES=<n> overrides the default per-wait budget (DEFAULT_MONITOR_BUDGET_CYCLES).

Enums§

MonitorWaitKind
Which monitor-wait instruction family this host runs.

Constants§

DEFAULT_MONITOR_BUDGET_CYCLES
Default monitor-tier budget in TSC cycles before escalating to the kernel park: ~25-30 us on contemporary 3-3.5 GHz parts. Sized to dominate a kernel park+wake round trip (single-digit us) so waits that resolve quickly never pay the syscall, while a genuinely idle waiter escalates to the zero-CPU park within tens of microseconds.

Functions§

monitor_wait_budget_cycles
The active per-wait budget in TSC cycles.
monitor_wait_kind
The monitor-wait family available on this host (None when the CPU exposes neither, when the build target is not x86_64, or when SUBETHA_NO_MONITOR_WAIT=1). Cached after the first call.
monitor_wait_u32
Wait on the monitor tier until *atomic != expected or the cycle budget expires.
monitor_wait_u64
As monitor_wait_u32 for a 64-bit atom (ring head counters and slot sequences are AtomicU64). Same protocol, same guarantees: the monitor watches the LINE, the width only affects the value re-check.
monitor_wait_u32_with
As monitor_wait_u32 with the family chosen explicitly (bench harnesses A/B the families; production callers use the probed default).
monitor_wait_u64_with