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.

Events (Event Loop): Single-threaded, non-blocking I/O.

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.

Result: $80 (The $10 deposit is lost!). Correct result should be $90.

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

  1. A process issues a file read system call.
  2. The kernel checks page cache; on a miss it schedules an I/O request.
  3. The I/O scheduler dispatches work to the device driver and blocks the thread.
  4. When the device interrupt arrives, the kernel copies data into memory pages.
  5. The scheduler wakes the blocked thread and resumes user-space execution.

Interactive: Syscall read path

Step 1 of 5

Failure modes

Trade-offs

Real-world usage

Standard Resources