Free preview

Why this matters: the prompt promised you'd defend when anyone should use this lock, and that's a judgment question, not a code question. This lesson is the judgment layer: the pathologies that make spinning the wrong answer, the hybrid that industry actually ships, and the measurements that turn lock arguments from vibes into numbers.

The preemption pathology

Lesson 01 surfaced the requirement that matters most here: the OS can deschedule a thread while it holds the lock. Walk what happens next, because it's the spinlock's defining failure mode: the holder is off-CPU, making no progress toward unlock — and every waiter is on-CPU, spinning at full speed on a lock that cannot be released until the scheduler happens to run the holder again. The waiters are burning the very resource the holder needs. On a machine with more runnable threads than cores, whole scheduling quanta — milliseconds — can vanish into microsecond-sized critical sections.

This is why the "short critical sections, low oversubscription" habitat isn't a preference but a load-bearing assumption: spinning is a bet that the holder is currently running. Preemption is the bet going wrong. Say it in exactly those terms and the "when to use this" question is already half-answered: kernels and pinned-thread systems can often guarantee the bet; general application code usually can't.

Priority inversion deserves a named mention in the same breath: if a low-priority thread holds the lock and a high-priority thread spins for it, the spinner can monopolize the CPU the holder needs — priority working against progress. It's a scheduling interaction, and OS mutexes have machinery for it that a raw spinlock does not.

Spin-then-park: the hybrid that ships

Given the pathology, why does anyone spin at all? Because parking — the OS-mutex path of putting a waiter to sleep and waking it later — costs syscalls and context switches, thousands of nanoseconds, which is obscene for a lock held for fifty. The industry answer refuses to choose: spin briefly, then park.

spin-then-park:
    spin (TTAS + backoff) for a bounded budget      // short holds: win
    still held?  park in the kernel                  // long holds: stop
                                                     // burning the core

Short critical sections resolve during the spin phase at spinlock speed; anything longer — including a preempted holder — falls through to a sleep that frees the CPU. This is what mainstream mutex implementations actually do under the name "adaptive": the OS mutex you were told to beat is often a spinlock with an exit strategy. The interview point: naming this collapses the false spinlock-versus-mutex binary into a budget-tuning question — how long to spin before giving up — which you can reason about (roughly: the cost of a park/unpark round trip).

cpu_relax: what the polite spin actually is

Lesson 03 left cpu_relax() as a placeholder. It stands for the CPU's spin-politeness hint — PAUSE on x86, YIELD on ARM — and it does real, prosaic work: it tells the pipeline "this is a spin-wait," de-prioritizing the loop so the physical core's resources go to the other hardware thread on the core, saving power and — usefully — slowing the spin's memory-probe rate. It is not a scheduler call: the OS-level sched_yield() is a different, heavier tool (surrender the timeslice entirely — occasionally the right move deep in a backoff, but a syscall, not a hint). Knowing the two "yields" apart is a small distinction that reads as real systems mileage.

Measuring before believing

Every claim in this chapter — TAS storms, TTAS calms, backoff helps, spinning beats parking under some hold-time — is a claim about your workload on your hardware, and the senior move is knowing how you'd check:

acquire latency     timestamp around lock(); plot the distribution,
                    not the mean — contention lives in the tail
spin wasted         count spin iterations (or time-in-loop) per
                    acquisition; converts "feels contended" to cycles
handoff traffic     hardware counters for cache-line transfers /
                    coherence events around the lock word
hold time           timestamp lock()->unlock(); validates the "short
                    sections" assumption the whole design rests on

Two design notes hiding in there: the counters themselves must not create contention (per-thread tallies, aggregated later — never a shared atomic counter next to the lock), and hold-time is the measurement most worth automating, because it guards the habitat assumption that justifies spinning at all.

Key takeaway

The spinlock's judgment layer: spinning is a bet that the holder is currently running — preemption is that bet failing, with waiters burning the CPU the holder needs, and priority inversion as its scheduling cousin. Industry hedges the bet with spin-then-park, making "spinlock versus mutex" a spin-budget question; cpu_relax is a pipeline hint, not a scheduler call; and every performance claim should end with how you'd measure it — tail latency, wasted spins, and above all hold time, the assumption the whole tool stands on.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue