0% found this document useful (0 votes)
5 views7 pages

OS Notes Detailed

The document provides an overview of operating system concepts including processes, threads, context switching, process scheduling, and memory management. It discusses the mechanisms of virtual memory, paging, caching, synchronization, inter-process communication, and virtualization. Additionally, it covers issues like deadlock, starvation, and the Linux directory structure.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views7 pages

OS Notes Detailed

The document provides an overview of operating system concepts including processes, threads, context switching, process scheduling, and memory management. It discusses the mechanisms of virtual memory, paging, caching, synchronization, inter-process communication, and virtualization. Additionally, it covers issues like deadlock, starvation, and the Linux directory structure.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1. PROCESS & THREAD 3.

CONTEXT SWITCHING

Process Mechanism by which OS pauses one process and resumes another — creates illusion of concurrency. Triggered by
timer interrupt, I/O block, or explicit yield. Pure overhead — no useful work during the switch itself (~1–10 µs including
A process is a program in execution — includes code, current activity (PC, registers), stack, heap, and data. Every
TLB flush + cache warm).
process has a unique PID and its own isolated virtual address space. Managed via the PCB (Process Control Block):
PID, state, CPU registers, PC, memory maps, open files, scheduling info. Step Action

State Meaning ① Interrupt/trap CPU transfers control to kernel

New Being created ② Save A's context Registers, PC, SP → A's PCB

Ready Waiting for CPU ③ Scheduler runs Picks next process B from ready queue

Running On CPU now ④ Load B's context Restores B's registers, PC, mem maps

Waiting Blocked on I/O/event ⑤ Switch mem maps MMU updated; TLB may flush (expensive)

Terminated Finished ⑥ Resume B CPU jumps to B's saved PC

Thread ★ Too-small time quanta in Round Robin → frequent context switches → overhead dominates useful work.

A thread is the smallest CPU execution unit. Threads in the same process share heap, code, and data but each has its
4. KERNEL & SYSTEM CALLS
own stack, registers, and PC. Cheaper to create/switch than processes.

Kernel Thread User Thread User Space vs Kernel Space


Scheduled by OS Library/runtime User mode: restricted — apps cannot touch hardware or execute privileged instructions. Kernel mode: full access —
manages hardware, memory, scheduling. Separation prevents buggy apps from crashing the OS or accessing other
Blocking syscall Blocks only that thread Blocks whole process
processes' memory.
Overhead Higher Lower
System Call Flow
★ Process isolation = safety. Thread sharing = speed. Race conditions are the price of sharing.
App needs privileged op → issues syscall → software interrupt → CPU switches to kernel mode → kernel validates +
executes → returns result → switches back to user mode. Cost: ~100s ns (mode switch + security check + possible
2. PROCESS SCHEDULING
reschedule) vs nanoseconds for a normal function call.
Preemptive: OS can interrupt running process (better responsiveness). Non-preemptive: runs until it yields/finishes App → glibc wrapper → syscall instruction → kernel → driver → hardware → return
(less overhead). Metrics: CPU utilization ↑, Throughput ↑, Turnaround/Waiting/Response time ↓.
Category Key Syscalls
Algorithm Type Idea Weakness
Process fork(), exec(), wait(), exit()
FCFS Non-pre Arrival order Convoy effect
File I/O open(), read(), write(), close(), lseek(), stat()
SJF Non-pre Shortest burst first Needs prediction; starvation
Memory mmap(), brk(), munmap()
SRTF Preemptive Preemptive SJF High overhead; starvation
IPC pipe(), socket(), shmget(), semget()
Round Robin Preemptive Fixed time quantum, rotate Small q→overhead; large q→FCFS
Network bind(), listen(), accept(), connect(), send(), recv()
Priority Both Highest priority first Starvation → fix: aging
File Descriptors & I/O Modes
Multilevel Q Non-pre Separate queues per job class No migration; rigid
Unix: everything is a file (files, sockets, pipes, devices) → integer FD. FD 0=stdin, 1=stdout, 2=stderr; inherited by child
Formulas: Turnaround = Completion − Arrival | Waiting = Turnaround − Burst | Response = FirstRun − Arrival via fork(). Blocking: thread sleeps until done. Non-blocking: returns EAGAIN immediately — used in event loops
★ Aging: gradually raise priority of waiting processes to prevent starvation in Priority scheduling. (epoll/kqueue). Interrupts: async hardware-triggered. Syscalls: sync process-triggered.

★ Syscall is expensive — libraries like libc batch operations (fwrite buffers) to minimise syscall frequency.
5. VIRTUAL MEMORY & ADDRESS SPACE 7. TLB (TRANSLATION LOOKASIDE BUFFER)
Each process believes it owns a large contiguous private address space. OS + MMU translate virtual→physical Page table lookup on every memory access = extra RAM read = slow. TLB: small hardware cache inside MMU storing
transparently. Enables isolation (no cross-process reads), simplifies programming, and allows running more processes recent VA→PA mappings. Hit: ~1 cycle. Miss: page table walk = 10–100+ cycles. Typical hit rate: 95–99%.
than RAM physically holds.
TLB Hit TLB Miss
Region Direction Contents Action Use cached mapping Walk page table → load → retry
Stack Grows ↓ Local vars, return addrs, function frames. Fixed max (ulimit). Stack overflow = Cost ~1 cycle ~10–100+ cycles
crash.
Frequency 95–99% 1–5%
↕ Gap — Unmapped — segfault on access. Prevents stack/heap collision.
Context switch + TLB: entries are invalid for new process. Either flush entire TLB (costly) or use ASIDs (Address
Heap Grows ↑ Dynamic memory (malloc/new). Allocator-managed. Fragmentation possible.
Space IDs) to tag entries per process — avoids full flush.
Data (.data/.bss) Fixed Initialized globals (.data) + zero-init globals (.bss).
EAT = h×(tlb+mem) + (1−h)×(tlb+2×mem) [h=hit rate]
Text/Code Fixed Read-only program instructions. Shared among threads. With h=0.99, TLB=1ns, Mem=100ns → EAT≈102ns vs 200ns without TLB.
★ Same virtual address in two processes → different physical RAM. This IS process isolation. ★ Locality of memory access directly determines TLB hit rate → program structure affects performance.

6. PAGING & ADDRESS TRANSLATION 8. CACHING & MEMORY HIERARCHY


Virtual + physical memory divided into fixed 4 KB blocks (pages / frames). Per-process page table maps page# → CPU executes billions ops/sec; RAM access ~100ns (~300 cycles). Caches bridge this gap by keeping recent/frequent
frame#. Eliminates external fragmentation; allows non-contiguous physical allocation. data close to CPU. Data flows down on miss, up on eviction.
VA = [Page# | Offset] PA = Frame# × PageSize + Offset
Level Latency Size Shared?
Example: VA=8200, PageSize=4096 → Page#=2, Offset=8. If Page2→Frame19: PA = 19×4096 + 8.
Registers <1 cycle <1 KB Per core
Multi-level Page Tables L1 Cache ~4 cycles 32–64 KB Per core
Flat page table for 64-bit space = enormous. Hierarchical tables allocate entries only for used regions. x86-64 uses 4
L2 Cache ~12 cycles 256KB–1MB Per core
levels (PML4→PDPT→PD→PT). Drastically reduces memory for sparse address spaces.
L3 Cache ~40 cycles 4–64 MB All cores
Demand Paging & Page Faults RAM ~200 cycles GBs All
Pages loaded only when first accessed (lazy). On access of unmapped page → page fault → OS finds page on disk
NVMe SSD ~50K cycles TBs All
→ loads into free frame → updates page table → restarts instruction. Process is unaware.
HDD ~5M cycles TBs All
Algorithm Idea Note
OPT Replace page unused longest in future Theoretical benchmark only Cache Lines & Locality
FIFO Evict oldest-loaded page Bélády's anomaly: more frames→more faults
Cache loads 64-byte cache lines, not individual bytes. Sequential array access = very fast (spatial locality). Random
pointer chasing = cache-unfriendly.
LRU Evict least recently used Good approx of OPT; costly to implement
Temporal: recently used data reused soon (loop counters, hot functions). Spatial: nearby addresses accessed soon
Clock FIFO + reference bit (2nd chance) Hardware-efficient LRU approx
(array traversal, sequential reads). Row-major traversal in C = good; column-major = bad.
LFU Evict least frequently used Slow to adapt to changing access patterns
Cache Coherence & False Sharing
★ Thrashing: working set > available frames → OS swaps more than it executes → CPU utilization collapses. MESI protocol (Modified/Exclusive/Shared/Invalid): keeps private per-core caches consistent — cores snoop bus
Fix: reduce multiprogramming or add RAM.
transactions and invalidate stale copies.
✔ Eliminates external fragmentation ✘ Internal fragmentation (last page) False sharing: two threads modify different variables on the same 64-byte cache line → constant invalidation even
✔ Enables demand paging & swap ✘ Page table overhead though no logical sharing. Fix: pad structs to align each thread's data to its own cache line.
✔ Process isolation via page tables ✘ TLB misses on sparse access
★ False sharing can silently destroy multi-core scalability — profile with perf/VTune before assuming
parallelism helps.

9. SYNCHRONIZATION

Race Condition & Critical Section


A race condition: correctness depends on timing of concurrent ops. counter++ = read/modify/write — interleaved
execution can lose increments. The critical section is code accessing shared state; must be protected.

★ 3 Requirements: ① Mutual Exclusion (one thread in CS) ② Progress (empty CS → waiter enters) ③ Bounded
Waiting (no starvation).
Mutex & Spinlock 11. INTER-PROCESS COMMUNICATION (IPC)
Mutex: binary lock — only holder can unlock. Spinlock: busy-waits in loop — no context switch, good for very short
critical sections (kernel, low-latency). Blocking mutex: thread sleeps if unavailable — better for longer waits; OS Processes have isolated address spaces. IPC = OS-provided channels for data exchange, synchronization, signaling.
wakes it on release. Kernel mediates all IPC for security. Choice involves speed vs complexity vs scope trade-offs.

✔ Spinlock: zero context-switch overhead ✘ Spinlock: wastes CPU cycles if long wait Mechanism Speed Scope Key Notes

✔ Blocking mutex: CPU freed while waiting ✘ Blocking mutex: context-switch overhead Signals Instant Local Async notify; SIGKILL/TERM/INT; no data transfer
Anon Pipe Fast Parent↔Chil Unidirectional byte stream; pipe()+fork()
Semaphores d
Integer counter with atomic wait(S)/P(): if S>0 decrement else block; and signal(S)/V(): increment + wake one blocked
Named Pipe Fast Any local FIFO file; unrelated processes
thread. Atomicity via hardware test-and-set or OS.
Shared Memory Fastest Local Direct RAM; needs mutex/sem for sync
Binary semaphore (0/1): acts like mutex. Counting semaphore (0…N): N concurrent users — DB connection pools,
bounded buffers, printer spoolers. Message Queue Medium Local Kernel-buffered structured msgs; decoupled
Unix Socket Very fast Local Bidirectional; used by DBs, Docker
Monitors & Classic Problems
TCP Socket Overhead Network Foundation of distributed systems
Monitor: high-level construct — all methods mutually exclusive. Condition variables: wait() releases lock + sleeps;
signal() wakes one waiter which re-acquires lock. Prevents missed-wakeup bug. RPC/gRPC Medium Network Serialised call; base of microservices

Problem Issue Solution ★ Shared memory = fastest IPC but REQUIRES explicit synchronization. Pipes are simplest but unidirectional
Producer-Consumer Don't overflow/underflow buffer 2 counting semaphores (empty,full) + 1 only.
mutex
12. VIRTUALIZATION
Readers-Writers Multiple readers OK; writer exclusive Reader count + mutex; writers exclude all
Run multiple OSes on one physical machine. Each OS (guest) runs in an isolated Virtual Machine (VM) with
Dining Philosophers 5 philosophers, 5 forks → deadlock risk Asymmetric pickup order or resource
ordering virtualised CPU, memory, disk, and network. The hypervisor (VMM) manages resource sharing.

Type Mechanism Perf Note


10. DEADLOCK, STARVATION & LIVELOCK
Emulated Binary translation of all privileged Slowest Guest OS unmodified; every privileged op
instructions intercepted in SW
Deadlock
Set of processes permanently blocked — each holds ≥1 resource and waits for one held by another. System makes no Para-Virt Guest OS modified to use 'hypercalls' Good Requires OS source; Xen, early VMware
progress. Example: A holds L1 waits L2; B holds L2 waits L1. HW-Assisted CPU VT-x/AMD-V traps priv Near-native Modern standard; no OS modification
instructions to HV
★ 4 Necessary Conditions (MCHC) — break ANY ONE to prevent: ① Mutual Exclusion ② Hold & Wait ③ No
Preemption ④ Circular Wait. SR-IOV NIC presents as multiple virtual cards; Native I/O AWS Enhanced Networking; max network
HV bypassed perf
Strategy How Trade-off
Type 1 Hypervisor Type 2 Hypervisor
Prevention Eliminate a condition (request all upfront, release Reduces utilization; may be impractical
before requesting more) Runs on Bare hardware (no host OS) On top of host OS

Avoidance Banker's Algo: grant only if safe state remains Needs max-need declaration upfront Examples ESXi, Hyper-V, KVM, Xen VirtualBox, VMware Workstation

Detection Allow deadlocks; cycle-detect in resource graph; Detection overhead + disruptive recovery Use case Datacenters, production Dev, testing, desktop
kill/rollback
Containers vs VMs
Ignorance Assume rare; reboot (most desktop OSes) Simple; ok if deadlocks truly rare
VMs virtualise full hardware stack — each runs own kernel. Containers (Docker/LXC) share host kernel, isolated via
Starvation & Livelock & Priority Inversion Linux namespaces (PID, network, mount, user) and cgroups (CPU, memory, I/O limits).
Starvation: process waits indefinitely; system progresses but one thread suffers. Fix: aging (raise priority over time). ✔ VMs: strong isolation, any OS ✘ VMs: heavy (GBs), slow startup
Livelock: threads actively react to each other but no useful work — hallway analogy. Fix: random back-off. ✔ Containers: lightweight (MBs), ms startup, efficient ✘ Containers: shared kernel = kernel vuln affects all
Priority inversion: Low-priority L holds resource needed by High H; Medium M preempts L → H blocked by M. Mars
Pathfinder (1997). Fix: priority inheritance — raise L to H's priority while L holds resource. 13. LINUX DIRECTORY STRUCTURE (FHS)
★ Deadlock = no progress anywhere. Starvation = one thread suffers. Livelock = active but stuck. Single-root hierarchy — everything hangs off /. Physical devices, virtual FSes, and network mounts all appear as
directories. No drive letters.
/ Root of entire filesystem /opt Optional 3rd-party software outside package Storage Hierarchy & RAID
manager RAID (Redundant Array of Independent Disks): combines multiple disks for performance and/or redundancy.
/bin /usr/bin — Essential user binaries: ls, cp, mv, /proc Virtual FS: live kernel+process info — RAID Level Technique Capacity Fault Tolerance Use
bash /proc/cpuinfo, /proc/[PID]/
RAID 0 Striping 100% None (any disk fail = data Max performance
/sbin /usr/sbin — Admin binaries: fdisk, iptables, /sys Virtual FS (sysfs): hardware topology, driver loss)
sshd params, power mgmt
RAID 1 Mirroring 50% 1 disk failure Critical data
/boot Kernel (vmlinuz), initrd, GRUB config — don't /run Runtime data since boot: PIDs, sockets, locks.
RAID 5 Striping + parity (distributed) (N-1)/N 1 disk failure Balanced perf/redundancy
delete! Cleared on reboot.
RAID 6 Striping + 2 parity (N-2)/N 2 disk failures High durability
/dev Device files: /dev/sda (disk), /dev/null, /tmp Temp files; world-writable; cleared on reboot
/dev/urandom RAID 10 RAID 1+0: mirror then stripe 50% 1 disk per mirror pair High perf + redundancy
/etc All system config: passwd, fstab, hosts, ssh/, /usr Largest: user programs (/usr/bin), libs (/usr/lib),
File Systems
cron.d headers, docs
Organises data on storage. Key structures: superblock (FS metadata), inode (file metadata: permissions, size,
/home User home dirs: /home/alice — contains /var Variable data: logs (/var/log), cache (/var/cache),
timestamps, block pointers — not the filename), directory entries (name→inode), data blocks.
.bashrc, .ssh/ spool, DB files
Journaling: write intent to journal before changes — replay on crash prevents corruption (ext4, NTFS, APFS). Hard
/lib /usr/lib — Shared libraries (.so); kernel /root Home of root (superuser) — separate from /home
link: another dir entry → same inode (same data). Symlink: file containing path — can cross FSes, can be broken.
modules in /lib/modules/ for recovery access
FS OS Notes
/media /mnt — Mount points for removable/temp /srv Data served by system: /srv/http, /srv/ftp
filesystems ext4 Linux Journaled, extents, 1 EB max volume. Default Linux FS.
XFS Linux High-performance, great for large files & parallel I/O.
14. I/O & STORAGE
NTFS Windows Journaled, ACLs, compression, encryption (EFS).
I/O Methods APFS macOS/iOS Copy-on-write, snapshots, strong encryption, SSD-optimised.
Method How Best for FAT32 Universal No journaling, 4 GB file limit. Universal compatibility (USB).
Programmed I/O CPU polls device in a loop — wastes CPU Trivial/fast devices only
ZFS Linux/BSD CoW, built-in RAID, checksums, snapshots, self-healing.
Interrupt-driven CPU does other work; device interrupts when done Slow devices (keyboard, disk)
★ Inodes store ALL file metadata EXCEPT the filename. Filename lives only in directory entries.
DMA (Direct Memory Device transfers data to RAM without CPU; CPU Large transfers (disk, NIC, GPU)
Access) notified only on completion 15. MEMORY MANAGEMENT (ADVANCED)
★ DMA is critical for performance — without it, every disk byte transfer would stall the CPU.
Allocation Algorithms
Disk Scheduling (HDD) Algorithm Strategy Weakness
HDDs have mechanical seek time (arm moves to track) + rotational latency. OS reorders pending requests to minimise First Fit First hole ≥ requested size Leaves fragments at start of memory
total seek distance.
Best Fit Smallest sufficient hole Creates tiny unusable leftover fragments
Algorithm Strategy Note
Worst Fit Largest hole Wastes large blocks; leaves medium
FCFS Service in arrival order Simple; poor seek optimization fragments
SSTF Service closest track first Low seek; starvation of far requests Next Fit First fit from last allocation point Spreads fragmentation evenly
SCAN (Elevator) Sweep back and forth across disk Fair; predictable; good throughput Buddy System Split/merge power-of-2 blocks Internal fragmentation up to 50%; fast merge
LOOK Like SCAN but reverses at last request, not More efficient than SCAN ★ Linux kernel uses the Buddy System for page allocation and Slab allocator for kernel objects.
end
C-SCAN One-directional sweep; jump back to start Uniform wait; avoids SCAN bias Buddy System
Memory split into power-of-2 sized blocks. Allocation: find smallest fitting power-of-2; split if needed. Deallocation:
★ SSDs have no seek time — FCFS or simple queuing works. NVMe uses multiple parallel queues (65535 merge adjacent same-size 'buddies' recursively → fast coalescing. Used in Linux page allocator (/proc/buddyinfo
queues × 65535 cmds).
shows current state).
Slab Allocator Thread Pool Pattern
Pre-allocates caches of frequently used kernel objects (inodes, PCBs, dentries, sockets). Objects initialised once and Pre-create N worker threads. Tasks submitted to a shared queue. Workers pull and execute tasks. Avoids thread
recycled — eliminates init overhead and fragmentation for fixed-size objects. Three states: full (all objects allocated), creation overhead per task. Key parameters: pool size (usually = CPU cores for CPU-bound; larger for I/O-bound),
partial (some free), empty (all free → returned to buddy system). queue capacity (bounded to apply back-pressure).

✔ Eliminates per-object init overhead ✘ Memory not released until slab empty ✔ Reuses threads → no create/destroy overhead ✘ Fixed pool size may under/over-provision
✔ Near-zero fragmentation for fixed objects ✘ Complex implementation ✔ Bounded resource usage ✘ Queue full → must block or reject
✔ Fast allocation from partial slabs ✘ Per-object overhead in metadata ✔ Easy task submission API ✘ Hard to handle task priorities

OOM Killer Async / Event-Loop Pattern


When physical RAM + swap is exhausted, Linux invokes the OOM Killer. Scores each process using: memory usage, Single thread handles thousands of connections via epoll (Linux) / kqueue (BSD/macOS) / IOCP (Windows). Register
swap usage, priority, whether process is privileged. Kills highest-scoring (least important, most wasteful) process to interest in events (socket readable, timer fired). Kernel notifies when ready. No threads blocked waiting — one loop,
free memory. Admins can tune oom_score_adj (-1000 to +1000) per process. many concurrent ops. Used by: [Link], Nginx, Redis.
while true: events = epoll_wait(fds) // block until ≥1 ready for event in events: handle(event)
Memory-Mapped Files (mmap)
// non-blocking
Map a file directly into a process's virtual address space. Reading the memory = reading the file; writing = writing back
(if MAP_SHARED). Huge advantage: OS page cache handles buffering — no explicit read()/write() syscalls needed. ★ Event loop = C10K solution. Thread-per-connection fails at scale (each thread ~8MB stack). One event loop
handles 100K+ connections.
Used by: dynamic linkers (loading .so), databases (SQLite, PostgreSQL shared buffers), large file processing.

★ mmap is how shared libraries are loaded — libc is mapped once physically and shared (read-only code Producer-Consumer with Channels
pages) across all processes. Producers put work into a buffered channel; consumers pull and process. Channel capacity controls back-pressure. If
full → producer blocks (or drops). If empty → consumer blocks. Decouples production rate from consumption rate.
16. CONCURRENCY PATTERNS Used in Go (goroutines + channels), Rust (mpsc), Java (BlockingQueue).

Memory Ordering & Fences ★ Rule of thumb: CPU-bound tasks → pool size = CPU cores. I/O-bound tasks → pool size = cores × (1 +
wait_time/compute_time).
CPUs and compilers reorder instructions for performance. In single-threaded code this is invisible. In multi-threaded
code it breaks assumptions. Memory barriers/fences prevent reordering across the barrier point.
17. LINUX INTERNALS
Order Type Meaning
LoadLoad No load reordered before another load CFS — Completely Fair Scheduler
Linux's default scheduler (since 2.6.23). Goal: every runnable process gets an equal share of CPU. Tracks vruntime
StoreStore No store reordered before another store
(virtual runtime — CPU time weighted by priority/nice value) per process. Always runs process with smallest vruntime.
LoadStore / StoreLoad Full barrier — most expensive; prevents all reordering Uses a red-black tree sorted by vruntime — O(log n) insert/delete, O(1) find-min.
acquire All subsequent reads/writes happen after this read nice values: -20 (highest priority) to +19 (lowest). Lower nice → vruntime accumulates slower → gets more CPU.
release All prior reads/writes happen before this write Preemption: on tick or wakeup, if current's vruntime > min vruntime + threshold → reschedule.

★ x86 has a strong memory model (TSO — Total Store Order). ARM/RISC-V are weakly ordered — need explicit ★ CFS guarantees fairness, not equal time slices. High-priority process just accumulates vruntime slower.
barriers.
cgroups (Control Groups)
Compare-And-Swap (CAS) & Lock-Free Kernel mechanism to limit, account, and isolate resource usage (CPU, memory, disk I/O, network) of process groups.
CAS: atomic instruction — if memory[addr] == expected, set it to new_value, return true; else return false. Foundation Hierarchical — nested groups. Used by: Docker (container resource limits), systemd (service limits), Kubernetes (pod
of all lock-free data structures. limits).
bool CAS(addr, expected, new_val): // atomic if *addr == expected: *addr = new_val; return true cgroup subsystem What it controls
else: return false
cpu / cpuacct CPU time allocation and accounting
Lock-free: at least one thread makes progress at all times (no deadlock possible). Wait-free: every thread makes
memory RAM + swap limits; OOM killer per cgroup
progress in bounded steps (stronger). Lock-free ≠ faster — high contention causes CAS retries that waste cycles (ABA
problem). blkio Block I/O bandwidth and IOPS limits

ABA Problem: CAS sees value A, another thread changes A→B→A. CAS succeeds incorrectly. Fix: version counter net_cls/net_prio Network packet classification and priority
(tagged pointer) — compare address AND version number together. pids Limit number of processes in group (fork bomb prevention)
Namespaces Out-of-Order Execution
Kernel feature that wraps global system resources in an abstraction — each namespace has its own isolated view. CPU doesn't execute instructions in program order — executes whichever is ready (inputs available). Uses a reorder
Foundation of containers. buffer (ROB) to track in-flight instructions and commit results in program order. Hides latency (e.g. cache miss stalls
one instruction while CPU executes others).
Namespace Isolates
pid Process IDs — container has its own PID 1
Pipeline stages: Front-end (fetch, decode, rename) → Issue queue (wait for operands) → Execution units → ROB →
Commit in order. Modern CPUs are 4–6 wide (issue 4–6 µops/cycle).
net Network interfaces, routes, iptables, sockets
★ Spectre/Meltdown (2018): exploited speculative OOO execution to leak data across security boundaries via
mnt Filesystem mount points — container's own /
cache timing side-channels.
uts Hostname and NIS domain name
Branch Prediction
ipc SysV IPC, POSIX message queues
CPU predicts direction of branches before they resolve to keep pipeline full. Static: always predict taken/not-taken.
user UID/GID mappings — root in container ≠ root on host
Dynamic: use history table (2-bit saturating counters) — learns patterns. Modern CPUs: 95–99% prediction accuracy.
cgroup cgroup root — hides host cgroup hierarchy Misprediction penalty: ~15–20 cycles (flush pipeline, restart from correct path).
★ Container = cgroups (resource limits) + namespaces (isolation) + overlay filesystem (layered images). No Indirect branch predictor: predicts target address (not just taken/not-taken) — used for virtual function calls, jump
hypervisor needed. tables. Return address stack: dedicated hardware stack for predicting function returns.

eBPF (Extended Berkeley Packet Filter) ✔ ~99% accuracy on regular loops and if-else ✘ Misprediction = 15–20 cycle penalty

Run sandboxed programs inside the Linux kernel without changing kernel source or loading modules. eBPF programs ✔ Hides branch latency completely when correct ✘ Spectre vulnerability — branch predictor exploitable
are JIT-compiled and verified for safety (no infinite loops, no invalid memory access). Attach to: network events,
NUMA (Non-Uniform Memory Access)
syscalls (kprobes/tracepoints), performance counters, LSM hooks.
Multi-socket servers: each CPU socket has local RAM. Accessing local RAM is fast (~100ns). Accessing another
Used by: Cilium (Kubernetes networking), Falco (security), bcc/bpftrace (observability), Facebook's network load socket's RAM crosses the interconnect (QPI/Infinity Fabric) — slower (~300ns). OS must be NUMA-aware to place
balancer (Katran). Enables zero-overhead tracing and custom kernel logic without reboots. processes near their memory. Linux: numactl, taskset.
★ eBPF is often called 'JavaScript for the kernel' — safe, dynamic, powerful kernel extensions without kernel Concept Detail
modules.
NUMA node CPU socket + its local RAM
Linux Boot & Init Local access Fast — same node
① UEFI/BIOS POST + hardware init. ② Bootloader (GRUB) loads kernel + initramfs into RAM. ③ Kernel decompresses Remote access ~2–3× slower — crosses interconnect
itself, initialises memory, CPU, scheduler, drivers. ④ Mounts initramfs as temporary root. ⑤ Pivots to real root
NUMA-aware alloc mmap with mbind(); numactl --membind
filesystem. ⑥ Launches systemd (PID 1). ⑦ systemd activates units (services, mounts, sockets) in dependency order.
⑧ Login prompt. False NUMA sharing Hot data on one node; all CPUs fight for it → remote access hell

★ systemd uses socket activation and parallel startup — much faster than SysV init's sequential script ★ On NUMA systems, memory locality can matter as much as cache locality. Profile with numastat.
execution.
CPU Registers & ISA
18. COMPUTER ARCHITECTURE General-purpose registers (x86-64): RAX, RBX, RCX, RDX, RSI, RDI, RSP (stack pointer), RBP (base pointer),
R8–R15. Special: RIP (instruction pointer), RFLAGS (condition codes). SIMD: XMM/YMM/ZMM registers
Instruction Pipeline (128/256/512-bit) for vectorised float/int operations (SSE/AVX).
Modern CPUs execute instructions in overlapping stages: Fetch → Decode → Execute → Memory → Write-back. RISC vs CISC: RISC (ARM, RISC-V) — simple fixed-size instructions, many registers, load/store architecture. CISC
Multiple instructions in-flight simultaneously (pipelined). Ideal: 1 instruction completes per cycle. A 5-stage pipeline can (x86) — complex variable-length instructions decoded into micro-ops internally. Modern x86 has a RISC core with
have 5 instructions in flight. CISC front-end.
Hazard Type Cause Fix
★ x86-64 calling convention: first 6 int args in RDI, RSI, RDX, RCX, R8, R9. Return value in RAX. Callee-saved:
Structural Two instructions need same HW resource Stall or duplicate hardware RBX, RBP, R12–R15.
Data Instruction needs result of previous instruction Forwarding (bypass) or stall (NOP bubbles)
Control (Branch) Next PC unknown until branch resolves Branch prediction; speculative execution
19. COMPILERS & LINKERS Compiler Optimisations
Optimisation What it does
Compilation Pipeline Constant folding Evaluate constant expressions at compile time: 3*8 → 24
Source → binary is a multi-stage process. Each stage transforms the representation.
Dead code elimination Remove code whose result is never used
Stage Tool Input→Output Key Action
Inlining Replace function call with function body — eliminates call overhead
Preprocessing cpp source.c → source.i Expand #include, #define, #ifdef macros
Loop unrolling Duplicate loop body N times — reduce branch/counter overhead
Compilation cc1 source.i → source.s Parse → AST → IR → optimise → assembly
Vectorisation (auto-SIMD) Use SIMD instructions (AVX) for loops over arrays automatically
Assembly as source.s → source.o Convert assembly to machine code + ELF relocations
Register allocation Keep hot variables in CPU registers, not stack
Linking ld *.o + libs → binary Resolve symbols, merge sections, fix addresses
Alias analysis Prove pointers don't alias → enable more aggressive reordering
ELF Format (Executable and Linkable Format) LTO (Link-Time Opt.) Optimise across compilation units at link time
Standard binary format on Linux/Unix. Contains:
GCC/Clang flags: -O0 (debug, no opt) -O2 (production default) -O3 (aggressive) -Os (size) -Ofast (ignore IEEE;
Section Contents dangerous) -flto (link-time opt)
.text Executable machine code (read-only)
★ Always profile before optimising. The compiler's -O2 is usually better than hand-tuned code. Premature
.data Initialized global/static variables optimisation is the root of all evil (Knuth).
.bss Uninitialised globals (just size stored; zeroed at load)
Position-Independent Code (PIC) & ASLR
.rodata Read-only data: string literals, const arrays PIC: code that works regardless of where it is loaded in memory. Uses relative addressing and GOT. Required for
.symtab /strtab — symbol table and string names (stripped in release) shared libraries (.so) and for ASLR. Slight overhead vs absolute addressing but negligible on modern CPUs.
.rel/.rela Relocation entries — addresses to fix up at link/load time ASLR (Address Space Layout Randomisation): OS loads stack, heap, libraries at random addresses each run. Makes
.plt/.got Procedure Linkage Table + Global Offset Table — for dynamic linking
buffer overflow exploits much harder (attacker can't predict addresses). Combined with NX bit (no-execute on data
pages) and stack canaries — modern exploit mitigations.
.debug_* DWARF debug info (line numbers, variable names, types)
★ ASLR + NX + Stack canary = the holy trinity of memory safety. All enabled by default in modern
★ Strip debug symbols (strip binary) for release — can reduce binary size 10×. Use separate .dSYM / .debug Linux/macOS/Windows.
files for crash analysis.

Static vs Dynamic Linking


Static Linking Dynamic Linking
How Library code copied into binary at link time Binary references library; loaded at runtime by
[Link]
Binary size Large (includes all libs) Small (libs shared)
Memory Each process has own copy All processes share same physical pages of .so
Updates Relink to update Replace .so — all apps get fix
Startup Faster (no runtime linking) Slower (PLT/GOT resolution)
Portability Self-contained; runs anywhere Needs correct .so version installed

★ Dynamic linking saves RAM (shared .so pages) but introduces 'dependency hell'. Docker solves this by
bundling libs in container.

Dynamic Linking: PLT & GOT


When code calls an external function (e.g. printf), it calls a PLT stub. The stub jumps via a GOT entry. On first call:
dynamic linker resolves the actual address and patches the GOT. Subsequent calls: GOT already has address →
direct jump (lazy binding). This is called lazy symbol resolution.
call printf → plt[printf] → GOT[printf] first call: GOT → linker → resolves → patches GOT next
calls: GOT → printf directly

You might also like