Operating Systems Fundamentals
Problem framing
Every distributed system rests on an operating system that multiplexes CPU, memory, and devices safely across workloads. The OS must provide isolation, fairness, and durability while hiding hardware complexity behind stable interfaces. The "three easy pieces" frame this as virtualization, concurrency, and persistence.
Core idea / pattern
Virtualization
Problem: many programs need to share hardware without corrupting each other. Pattern: processes, virtual address spaces, context switches, and protected modes that make resources appear private even when they are shared.
Concurrency
Problem: multiple threads interleave unpredictably, risking races and starvation. Pattern: schedulers, locks, and coordination primitives that constrain interleavings while keeping throughput high.
Deep Dive: Threads vs Events
Threads: OS-scheduled units of execution.
- Positives: Can use multiple cores (parallelism). Blocking is easy (OS suspends thread).
- Negatives: Context switching overhead. Synchronization (locks) is hard/error-prone.
Events (Event Loop): Single-threaded, non-blocking I/O.
- Positives: Low overhead (no context switches). No locking needed for shared state (run-to-completion).
- Negatives: Cannot use multiple cores directly. CPU-bound tasks block the loop. Callback hell.
Race Condition
A race condition occurs when the behavior of a system depends on the relative timing of events, such as the order in which threads are scheduled. If two threads access shared data without synchronization, the result can be unpredictable.
Example: The Bank Balance
Initial Balance: $100.
- Thread A reads $100.
- Thread B reads $100.
- Thread A adds $10. writes $110.
- Thread B subtracts $20. writes $80.
sequenceDiagram
participant TA as Thread A
participant M as Memory (Balance)
participant TB as Thread B
Note over M: Balance = 100
TA->>M: Read Balance (100)
TB->>M: Read Balance (100)
Note over TA: Calc 100 + 10 = 110
TA->>M: Write Balance (110)
Note over TB: Calc 100 - 20 = 80
TB->>M: Write Balance (80)
Note right of M: Lost Update! (110 overwritten)
Persistence
Problem: data must survive crashes and power loss. Pattern: buffering, write-ahead logging, and journaling file systems that make durable state predictable.
| Piece | Goal | Primary mechanisms | Typical failures |
|---|---|---|---|
| Virtualization | Isolation and multiplexing | Processes, virtual memory, traps | Address corruption, leaks |
| Concurrency | Correctness under interleaving | Scheduling, locks, signals | Deadlock, starvation |
| Persistence | Durable state | Journaling, buffering, fsync | Corruption after crash |
Architecture diagram
flowchart TB
App[Applications] --> Syscall[System Call API]
Syscall --> Kernel[Kernel]
Kernel --> Sched[CPU Scheduler]
Kernel --> VM[Virtual Memory]
Kernel --> FS[File System]
Kernel --> Driver[Device Drivers]
Driver --> HW[Hardware]
Step-by-step flow
- A process issues a file read system call.
- The kernel checks page cache; on a miss it schedules an I/O request.
- The I/O scheduler dispatches work to the device driver and blocks the thread.
- When the device interrupt arrives, the kernel copies data into memory pages.
- The scheduler wakes the blocked thread and resumes user-space execution.
Interactive: Syscall read path
Failure modes
- Deadlocks or priority inversion stall critical threads.
- Memory leaks or runaway allocations trigger out-of-memory kills.
- Thrashing occurs when working sets exceed physical memory.
- Unflushed buffers lead to data loss after sudden power failure.
- Kernel bugs propagate into system-wide outages.
Trade-offs
- Preemptive scheduling improves fairness but can reduce cache locality.
- Larger page sizes reduce TLB pressure but increase fragmentation.
- Write-back caching boosts throughput yet increases durability risk.
- Sync I/O offers predictability at the cost of latency and throughput.
- Isolation primitives improve safety but add overhead.
Real-world usage
- Linux CFS balances throughput and fairness across CPU-bound workloads.
- cgroups and namespaces enable container isolation for Kubernetes.
- Journaling file systems like ext4 and XFS protect against partial writes.
- Copy-on-write systems like ZFS and btrfs ease snapshots and rollback.
Standard Resources
- Operating Systems: Three Easy Pieces - Arpaci-Dusseau (Standard textbook)
- xv6: a simple, Unix-like teaching operating system - MIT