Skip to content

Synchronization

Overview

Synchronization mechanisms coordinate concurrent execution and protect shared resources in multi-threaded and multi-core systems.

Linux provides multiple synchronization primitives designed for different workloads and performance requirements.

This topic covers traditional locking mechanisms, lockless read techniques, and object lifetime management.


Learning Path

Userspace Synchronization

  1. Locking Primitives - mutexes, condition variables, futexes, and reader-writer locks

Kernel Synchronization

  1. Wait Queue - event-driven kernel thread synchronization
  2. Completion - one-shot operation synchronization
  3. Notifier Chain - kernel event broadcast and callback framework
  4. Seqlock - lockless readers with consistent snapshots
  5. RCU - object publication, grace periods, and lifetime management

Synchronization Design Overview

Mechanism Primary Goal Reader Cost Writer Cost Best For
Mutex Mutual exclusion Medium Medium Shared mutable state
Condition Variable Event waiting N/A N/A Producer-consumer patterns
Semaphore Resource counting N/A N/A Resource coordination
Wait Queue Condition-based waiting Low Low Event-driven kernel threads
Completion One-shot synchronization Low Low Initialization and operation completion
Notifier Chain Event propagation Low Low One-to-many event notification
RWLock Read-heavy workloads Medium High Frequent reads
Seqlock Consistent snapshot Very Low Medium Statistics and timekeeping
RCU Object lifetime management Very Low High Read-mostly object access

Choosing the Right Primitive

Use Mutex When

Only one thread may access shared data at a time.

Examples:

Device state
Configuration updates
Linked list modifications

Use Condition Variable When

One thread must wait for another thread
to change system state.

Examples:

Producer-consumer queue
Worker thread notification

Use Wait Queue When

Threads must wait until a condition becomes true.

Examples:

Kernel state machines
Worker threads
Producer-consumer pipelines
Event-driven processing

Use Completion When

One execution context waits for another
operation to finish.

Examples:

Hardware initialization
Firmware loading
DMA completion
Worker startup synchronization

Use Notifier Chain When

One subsystem must notify multiple
independent subscribers about an event.

Examples:

CPU frequency changes
Power management events
Reboot notifications
Network device state changes

Use RWLock When

Reads are much more frequent than writes.

Examples:

Configuration tables
Lookup tables

Use Seqlock When

Readers require a consistent snapshot
and occasional retries are acceptable.

Examples:

Statistics
Timekeeping
System state snapshots

Use RCU When

Readers frequently access shared objects
and writers occasionally replace them.

Examples:

Routing tables
Device lookup tables
Kernel object registries

Relationship Between Topics

The synchronization mechanisms covered in this handbook build progressively:

Mutex
Condition Variable
Wait Queue
Completion
Notifier Chain
RWLock
Seqlock
RCU

As the progression advances:

More Reader Scalability
Less Reader Overhead
More Complex Writer Logic

Summary

Synchronization is not a single technique but a collection of mechanisms designed for different concurrency problems.

The key design skill is selecting the synchronization primitive that best matches the workload, data access pattern, and performance requirements of the system.