2026-07-16
Spin-waiting burns power and steals SMT resources from the sibling thread. The x86 MONITOR/MWAIT instruction pair lets a core tell the hardware "wake me when this specific address gets written," then park in a low-power state until it happens — no polling required.
How the hardware actually implements it:
The catch: the monitor is armed against a physical cache line, not your logical variable. If the write hits a different line, you sleep forever (until the next interrupt). And spurious wake-ups happen — coherence traffic on the same line from unrelated false-sharing counts. You must re-check the condition in a loop.
Real-world example: Linux's idle loop uses MWAIT to sleep on the need_resched flag of the per-CPU task_struct. When the scheduler on another core wants to wake this CPU, it just writes that byte — the coherence invalidation trips the monitor and the idle core wakes in ~100ns without ever executing a polling instruction. Compare that to a HLT-based idle that only wakes on interrupts (requiring an IPI, ~1µs+).
DPDK and Intel's umwait (user-mode variant, added in Tremont/Tiger Lake) use this for lock-free queues: producer writes a slot, consumer sleeps on the slot's address, wakes on the coherence poke. No syscall, no futex, no interrupt.
Rule of thumb: if you have a tight polling loop checking a single memory location that changes infrequently (say, less than once per microsecond), MWAIT saves roughly 1–5W per hyperthread and frees the sibling SMT thread to run at full speed. Below ~200ns between updates, the wake-up latency eats the win — just spin.
MWAIT is a ring-0 instruction historically; UMWAIT/UMONITOR extended it to userspace with a max-timeout MSR so a rogue process can't sleep forever.
