Operating Systems Cheatsheet
I/O Systems
Use this Operating Systems reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
I/O Hardware Overview
I/O devices communicate with the CPU via ports, buses, and device controllers.
| Component | Role |
|---|---|
| Device controller | Manages one device type; has registers (status, command, data) |
| I/O port | Fixed address in I/O address space; CPU uses in/out instructions |
| Memory-mapped I/O | Device registers mapped into physical address space; use regular load/store |
| Bus | Shared communication path (PCIe, USB, SATA, NVMe) |
| DMA controller | Transfers data between device and memory without CPU involvement |
I/O Interaction Methods
| Method | CPU involvement | Use case |
|---|---|---|
| Polling (busy wait) | 100% (spin-reads status register) | Very fast devices, real-time |
| Interrupt-driven | Only on completion | General purpose |
| DMA | Setup only; device writes directly to RAM | High-bandwidth (disk, NIC) |
DMA Transfer Sequence
1. CPU programs DMA: source, dest (physical addr), count, direction 2. CPU resumes other work 3. DMA controller transfers data word-by-word (or burst) over bus 4. DMA raises interrupt when done 5. CPU handles interrupt: verify status, continue
Cycle stealing: DMA steals bus cycles from CPU; slight CPU slowdown but overall faster than CPU copying.
I/O Software Layers
┌───────────────────────────────┐
│ User-level I/O library │ printf, fread, fwrite (buffering)
├───────────────────────────────┤
│ Device-independent OS layer │ open/read/write syscalls, naming, buffering, spooling
├───────────────────────────────┤
│ Device drivers │ Per-device; interrupt handlers
├───────────────────────────────┤
│ Interrupt handlers │ Save state, service, signal upper layer
├───────────────────────────────┤
│ Hardware │ Device controllers
└───────────────────────────────┘Device Drivers
Each device driver implements a standard interface (struct file_operations in Linux):
| Function pointer | Purpose |
|---|---|
open | Initialize device |
release | Cleanup |
read | Transfer data from device to user |
write | Transfer data from user to device |
ioctl | Device-specific control commands |
mmap | Map device memory to user space |
poll | Support select/poll/epoll |
llseek | Reposition file pointer |
Disk I/O and Scheduling
Disk Structure
- Platter → track → sector (512B or 4096B)
- Cylinder: same track number across all platters
- Seek: move arm to track (10–20 ms)
- Rotational latency: wait for sector (avg = half rotation ≈ 4 ms at 7200 RPM)
- Transfer: read/write (small)
Total time = seek time + rotational latency + transfer time
Disk Scheduling Algorithms
Reference string of track requests: 98, 183, 37, 122, 14, 124, 65, 67 (head starts at 53)
| Algorithm | Order | Total seek (tracks) | Notes |
|---|---|---|---|
| FCFS | 53→98→183→37→122→14→124→65→67 | 640 | Simple, no starvation |
| SSTF (Shortest Seek Time First) | 53→65→67→37→14→98→122→124→183 | 236 | Starvation of outer tracks |
| SCAN (Elevator) | 53→65→67→98→122→124→183→37→14 | 236 | No starvation |
| C-SCAN (Circular SCAN) | 53→65→67→98→122→124→183→14→37 | 382 | Uniform wait time |
| LOOK | Like SCAN but only goes as far as last request | ~208 | Better than SCAN |
| C-LOOK | Circular LOOK | Better than C-SCAN | Default on many OSes |
SSDs have no moving parts — seek/rotational latency irrelevant. NVMe SSDs use parallel I/O queues; disk scheduling is minimal.
I/O Buffering
| Strategy | Description | Use |
|---|---|---|
| No buffering | Data copied directly between device and user | Rare (real-time) |
| Single buffer | OS buffer; process works while OS fills next | Simple |
| Double buffer | Two alternating buffers; overlap I/O + processing | Better throughput |
| Circular buffer | Ring of buffers; producer/consumer model | Streaming |
Spooling (Simultaneous Peripheral Operations On-Line): writes go to disk queue (spool); device drains queue. Used for printers, batch jobs.
Block vs Character Devices
| Type | Access | Examples | Buffering |
|---|---|---|---|
| Block device | Random; fixed-size blocks | Disk, SSD, USB drive | Yes (page cache) |
| Character device | Sequential stream | Keyboard, serial port, terminal | No (or line buffer) |
I/O Completion Notification
| Mechanism | Description | API |
|---|---|---|
| Blocking I/O | Thread sleeps until I/O done | read() default |
| Non-blocking I/O | Returns immediately; EAGAIN if not ready | O_NONBLOCK flag |
| Asynchronous I/O (AIO) | Submit request; get notified on completion | io_submit, io_uring |
select / poll | Monitor multiple fds; return when any ready | select(nfds, …) |
epoll | Scalable event notification; O(1) per event | epoll_create, epoll_wait |
io_uring (Linux 5.1+) | Ring buffers for zero-syscall async I/O | io_uring_setup |
select vs epoll Scaling
select / poll | epoll | |
|---|---|---|
| Syscall per wait | O(n) — pass all fds | O(1) — kernel tracks |
| Max fds | 1024 (FD_SETSIZE) | Millions |
| New event scan | O(n) kernel scan | O(1) event list |
| Suitable for | Small n | High-connection servers |
RAID Levels
Redundant Array of Independent Disks — combine multiple disks for performance and/or reliability.
| Level | Min disks | Redundancy | Read perf | Write perf | Usable space |
|---|---|---|---|---|---|
| RAID 0 (striping) | 2 | None | N× | N× | 100% |
| RAID 1 (mirroring) | 2 | Full copy | 2× read | 1× | 50% |
| RAID 4 | 3 | Parity disk | N−1× | 1× (parity bottleneck) | (N−1)/N |
| RAID 5 | 3 | Distributed parity | N× | ~N× (parallel writes) | (N−1)/N |
| RAID 6 | 4 | Dual parity | N× | Slower writes | (N−2)/N |
| RAID 10 (1+0) | 4 | Mirrored stripes | N× | N/2× | 50% |
RAID is not a backup — protects against disk failure, not accidental deletion or corruption.
Kernel I/O Subsystem: Page Cache
Disk reads cached in memory (page cache). Subsequent reads served from RAM. Writes: write-back (delay to disk) or write-through (immediate).
dirty ratio: max % of RAM that can be dirty pages before writes are forced (/proc/sys/vm/dirty_ratio).