A topic in the Open Knowledge Graph — a free, open map of 15,290 topics and the order to learn them in.

Spinlocks and Busy-Waiting Synchronization

College Depth 108 in the knowledge graph ☐ I know this ☆ Set as goal
417prerequisites beneath it
See this on the map →
Mutual Exclusion and LocksAtomic Operations and Compare-and-Swap+2 more→
synchronization locks multiprocessor

Core Idea

Spinlocks are synchronization primitives where a process repeatedly checks a lock in a loop without yielding the CPU. They are efficient for very short critical sections on multiprocessor systems but waste CPU cycles on single-processor systems or under high lock contention. The choice between spinlocks and blocking locks depends on expected contention and critical section duration.

Explainer

From your study of mutual exclusion and locks, you know that when a thread finds a lock already held, it must wait. The question is *how* it waits. A blocking lock (like a mutex) puts the waiting thread to sleep and asks the OS scheduler to run something else — the thread gives up the CPU until the lock holder signals that the lock is free. A spinlock takes the opposite approach: the waiting thread stays on the CPU and continuously checks the lock in a tight loop, "spinning" until it becomes available. Think of it as the difference between taking a number at a deli counter and sitting down (blocking) versus standing at the counter watching the clerk and asking "is it my turn yet?" over and over (spinning).

Spinning sounds wasteful, and on a single-processor system it genuinely is. If only one CPU exists, the thread holding the lock cannot make progress while the spinner occupies the processor — spinning just burns cycles until the OS preempts the spinner and schedules the lock holder. But on a multiprocessor system, the lock holder is running on a different CPU and actively making progress. If the critical section is very short — say, updating a single counter or pointer — the lock will be released in a few dozen nanoseconds. In that scenario, the cost of spinning is far less than the cost of a context switch, which you know involves saving registers, switching page tables, and potentially flushing caches. The breakeven point is roughly: if the expected wait time is less than the cost of two context switches (one to sleep, one to wake up), spinning wins.

This is why spinlocks are the synchronization primitive of choice inside operating system kernels for protecting short critical sections, especially on multiprocessor machines. Interrupt handlers, scheduler code, and memory allocators all use spinlocks because they cannot afford to sleep — sleeping inside the scheduler would be circular. A common pattern is spin-then-block: try spinning for a brief period, and if the lock is still held, fall back to blocking. This hybrid approach, sometimes called an adaptive lock, captures the best of both worlds: fast acquisition when contention is low, and CPU-efficient waiting when contention is high.

The implementation of a spinlock relies on the atomic hardware instructions you studied, such as test-and-set or compare-and-swap. A minimal spinlock is just a loop: `while (test_and_set(&lock) == 1) { /* spin */ }`. When the lock variable is 0, test-and-set atomically sets it to 1 and returns 0, and the thread enters the critical section. When the lock is already 1, test-and-set returns 1, and the thread keeps looping. The danger is priority inversion: if a low-priority thread holds a spinlock and a high-priority thread spins on it, the high-priority thread wastes its entire time slice spinning while the low-priority thread cannot run to release the lock. Real spinlock implementations address this with techniques like disabling preemption while holding the lock, ensuring the holder runs to completion quickly.

Practice Questions 5 questions

Prerequisite Chain

Understanding Zero → The Number Zero → Counting to Five → Counting to 10 → Counting to 20 → Counting a Set of Objects Up to 20 → Cardinality: The Last Number Counted → Matching Numerals to Quantities → Subitizing Small Quantities → Addition Within 10 → Number Bonds to 10 → Addition Within 20 → Doubles and Near Doubles → Doubles Facts Within 10 → Near Doubles Facts Within 20 → Mental Math Strategies for Addition → Mental Math: Adding and Subtracting Tens → Addition Within 100 → Repeated Addition as Multiplication → Multiplication as Equal Groups → Multiplication: Arrays → Basic Multiplication Facts (0s, 1s, 2s, 5s, 10s) → Multiplication Facts Within 100 → Division as Equal Sharing → Division as Grouping (Measurement Division) → Division: Grouping (Repeated Subtraction) Model → Division: Fair Sharing Model → Division as Equal Sharing → Division as Grouping → Basic Division Facts → Division Facts Within 100 → Multiplication and Division Fact Families → Relationship Between Multiplication and Division → Division Facts as Inverse of Multiplication → Remainders and Quotients in Division → Division Word Problems → Multi-Step Word Problems → Solving Multi-Step Word Problems → Multiplication Word Problems → Division Word Problems → Introduction to Long Division → Factors and Multiples → Prime and Composite Numbers → Equivalent Fractions → Relating Fractions and Decimals → Decimal Place Value → Integers and the Number Line → Comparing and Ordering Integers → Absolute Value → Adding Integers → Subtracting Integers → Multiplying Integers → Introduction to Exponents → Order of Operations → Integer Order of Operations → Variable Expressions → The Distributive Property → Variables and Expressions Review → Introduction to Polynomials → Adding and Subtracting Polynomials → Multiplying Polynomials → Factorial → Permutations → Combinations → Counting Principles: Addition and Multiplication Rules → Introduction to Graph Theory → Propositional Logic Foundations → Logical Equivalences → Boolean Algebra → Boolean Type and Truth Values → Comparison Operators and Boolean Tests → Logical Operators and Boolean Algebra → Boolean Algebra and Fundamental Laws → Logic Gates Fundamentals → Implementing Boolean Functions with Gates → Karnaugh Map Simplification → Combinational Circuit Design → Flip-Flops and Latches → Binary Counters: Design and Analysis → Binary Arithmetic → Fixed-Point Number Representation → Two's Complement Representation → Overflow and Underflow Detection → Binary Adders: Half-Adders and Full-Adders → Full Adder and Carry Propagation → Carry Lookahead Adder Design → Half Adder Circuit Design → Multiplication Circuit Design → Sequential Circuit Design → Registers and Register Files → Instruction Set Architecture (ISA) → Kernel Architecture and OS Structure → System Calls and User/Kernel Mode → Processes and the Process Control Block → Process Creation: fork() and exec() → Process Termination and Resource Cleanup → Process States and State Transitions → Process Model Formalization → Context Switching and CPU Dispatch → CPU Scheduling Fundamentals → Round-Robin (RR) Scheduling → First-Come-First-Served (FCFS) Scheduling → Scheduling Fairness and Starvation Prevention → Thread Scheduling and Coordination → Semaphores → Counting Semaphores and Resource Pools → Producer-Consumer Problem: Classic Synchronization → Barrier Synchronization Primitives → Spinlocks and Busy-Waiting Synchronization

Longest path: 109 steps · 417 total prerequisite topics

Prerequisites (4)

Leads To (0)

No topics depend on this one yet.