Operating Systems

The most-examined subject on any CS syllabus. Processes and threads, scheduling, synchronisation, deadlock, virtual memory, page replacement, file systems and disk scheduling.

If you remember nothing else

  • A process has its own address space; threads of one process share it — that single fact explains every difference between them.
  • Deadlock needs all four of mutual exclusion, hold-and-wait, no preemption and circular wait; breaking any one prevents it.
  • A context switch is pure overhead — the CPU does no useful work while saving one PCB and loading another.
  • Virtual memory gives each process a private address space larger than RAM; the MMU translates and the TLB caches those translations.
  • Belady's anomaly — more frames causing more page faults — affects FIFO but never LRU or Optimal, because those are stack algorithms.
  • Thrashing is when a process spends more time paging than executing; the cure is to reduce the degree of multiprogramming, not to add more swap.

What an operating system is

FunctionWhat it provides
Process managementCreation, scheduling, termination, synchronisation, IPC
Memory managementAllocation, address translation, protection, virtual memory
File managementDirectory structure, access control, allocation of blocks
Device managementDrivers, buffering, spooling, interrupt handling
Protection & securityIsolation between processes, authentication, access control

Kernel mode and user mode

The CPU carries a mode bit. In kernel (supervisor) mode every instruction is permitted, including I/O and memory-mapping instructions. In user mode privileged instructions trap. This is the hardware support that makes protection possible — without it, any program could rewrite the page tables and the OS would be merely advisory.

Kernel designRuns in kernel spaceTrade-offExamples
MonolithicEverything: scheduler, memory, file systems, driversFast — no message passing — but a driver bug can crash the systemLinux, traditional Unix
MicrokernelOnly IPC, scheduling and basic memory managementRobust and modular, but IPC between servers costs performanceQNX, MINIX, seL4
HybridA microkernel design with performance-critical parts pulled back inA pragmatic middle groundWindows NT, macOS (XNU)

Processes and the PCB

Process stateMeaningLeaves when
NewBeing createdAdmitted to the ready queue
ReadyWaiting for a CPUThe scheduler dispatches it
RunningExecuting on a CPUIt is preempted, blocks, or exits
Waiting / BlockedWaiting for I/O or an eventThe event completes → back to Ready
TerminatedFinished; awaiting cleanupThe parent reaps its exit status

The Process Control Block

The PCB is the kernel's record of a process — everything that must be saved to suspend it and restored to resume it: process ID and parent ID, current state, program counter, CPU registers, scheduling information (priority, queue pointers), memory-management information (page-table or segment-table base), accounting data, and the list of open files and I/O devices.

Cfork() and the classic counting question
pid_t pid = fork(); // Returns TWICE: 0 in the child, the child's PID in the parent, -1 on failure. // The child gets a copy of the parent's address space (copy-on-write in practice). if (pid == 0) printf("child\n"); else if (pid > 0) printf("parent\n"); // How many processes does this create? fork(); fork(); fork(); // 2^3 = 8 processes total (7 new children). Each fork doubles the count. // exec() REPLACES the current image - it does not return on success. // The fork-then-exec pair is how Unix starts a new program.

Threads

ProcessThread
Address spacePrivateShared with sibling threads
Owns privatelyEverythingStack, registers, program counter, thread-local storage
SharesNothing without explicit IPCCode, data, heap, open files, signals
Creation costHigh — new page tables, new PCBLow
Context switch costHigh — TLB flush, cache pollutionLow — same address space, no TLB flush
CommunicationIPC: pipes, shared memory, message queuesDirect — just read shared variables
Fault isolationA crash kills only that processA crash kills the whole process
ModelMappingConsequence
Many-to-oneMany user threads → one kernel threadFast switching in user space, but one blocking call blocks all threads, and no real parallelism
One-to-oneEach user thread → one kernel threadTrue parallelism and independent blocking; kernel thread count must be bounded. Used by Linux and Windows
Many-to-manym user threads → n kernel threadsFlexible and scalable, but complex to implement

CPU scheduling

CriterionDefinitionGoal
CPU utilisationFraction of time the CPU is busyMaximise
ThroughputProcesses completed per unit timeMaximise
Turnaround timeCompletion − arrivalMinimise
Waiting timeTurnaround − burst; time spent in the ready queueMinimise
Response timeFirst scheduled − arrivalMinimise — matters most for interactive work
AlgorithmPreemptive?SelectsStrengthWeakness
FCFSNoEarliest arrivalTrivially simple and fairConvoy effect — one long job delays everyone
SJFNoShortest next burstProvably minimal average waiting timeBurst length is not known in advance; starves long jobs
SRTFYesShortest remaining timeBetter average than SJFSame problems, plus more context switches
PriorityEitherHighest prioritySupports importance levelsStarvation — cured with ageing
Round RobinYesNext in queue, one quantum eachExcellent response time; no starvationHigher average turnaround; sensitive to quantum size
Multilevel queueYesBy queue classSeparates interactive from batchRigid — a process never changes queue
Multilevel feedbackYesBy queue, with movement between themAdapts to observed behaviour; the general-purpose answerMany parameters to tune
Plain textWorked example — compute the averages
Process Arrival Burst P1 0 7 P2 2 4 P3 4 1 P4 5 4 FCFS order: P1(0-7) P2(7-11) P3(11-12) P4(12-16) Waiting = start - arrival: P1=0, P2=5, P3=7, P4=7 -> avg 4.75 SJF (non-preemptive): P1(0-7) P3(7-8) P2(8-12) P4(12-16) Waiting: P1=0, P3=3, P2=6, P4=7 -> avg 4.00 SRTF (preemptive): P1(0-2) P2(2-4) P3(4-5) P2(5-7) P4(7-11) P1(11-16) Waiting: P1=9, P2=1, P3=0, P4=2 -> avg 3.00 Note SRTF <= SJF <= FCFS on average waiting time. That ordering is the point of the exercise.

Inter-process communication

MechanismHowNotes
Shared memoryTwo processes map the same physical framesFastest — no kernel copy after setup — but you must synchronise
PipesA unidirectional byte streamAnonymous pipes need a common ancestor; named pipes (FIFOs) do not
Message queuesThe kernel holds discrete messagesPreserves message boundaries; kernel-mediated, so slower
SocketsEndpoints, local or across a networkThe only option that spans machines
SignalsAsynchronous notification of an eventCarries almost no data; handlers must be async-signal-safe

Synchronisation

CWhy counter++ loses updates
// counter++ compiles to roughly: // LOAD R1, counter // ADD R1, 1 // STORE counter, R1 // With counter = 5 and two threads incrementing: // T1: LOAD R1 = 5 // T2: LOAD R1 = 5 <- context switch before T1 stored // T1: ADD -> 6, STORE 6 // T2: ADD -> 6, STORE 6 <- overwrites; counter is 6, should be 7

Any correct solution to the critical section problem must satisfy three requirements:

  1. Mutual exclusion

    At most one process is inside its critical section at any time.
  2. Progress

    If no process is in its critical section and some wish to enter, only those wishing to enter participate in the decision, and it cannot be postponed indefinitely.
  3. Bounded waiting

    There is a limit on how many times other processes may enter after a process has requested entry — this is what rules out starvation.
PrimitiveWhat it isKey property
Mutex lockBinary lock with ownershipOnly the thread that locked it may unlock it. Use for mutual exclusion
Binary semaphoreCounter capped at 1, no ownershipAny thread may signal it — usable for signalling between threads
Counting semaphoreCounter over a resource poolwait() decrements and blocks at 0; signal() increments. Use for N identical resources
MonitorA language construct: data plus procedures with automatic mutual exclusionOnly one thread active inside at a time; condition variables provide wait/signal
SpinlockA lock that busy-waits rather than blockingCorrect only when the wait is shorter than a context switch — i.e. inside multiprocessor kernels

The three classic problems

ProblemThe difficultyStandard solution
Producer-Consumer (bounded buffer)Producers must block when full, consumers when emptyTwo counting semaphores (empty, full) plus a mutex for the buffer
Readers-WritersAny number of readers may share; a writer needs exclusive accessA reader count guarded by a mutex, plus a write lock. Prone to starving one side — hence reader-priority and writer-priority variants
Dining PhilosophersFive philosophers, five forks, each needs two — naive code deadlocksBreak circular wait: have one philosopher pick up forks in the opposite order, or allow at most four at the table

Deadlock

ConditionMeaningHow to break it
Mutual exclusionAt least one resource is non-shareableMake resources shareable — often impossible; a printer cannot be shared
Hold and waitA process holding resources requests moreRequire all resources be requested at once; hurts utilisation and can starve
No preemptionResources cannot be forcibly takenAllow preemption — practical for CPU and memory, not for a half-written file
Circular waitA cycle exists in the wait-for graphImpose a global ordering on resources and require requests in increasing order — the most practical of the four
StrategyApproachCost
PreventionStructurally negate one of the four conditionsLow resource utilisation; restrictive
AvoidanceGrant a request only if the system stays in a safe state (banker's algorithm)Requires knowing maximum needs up front; expensive to run
Detection & recoveryLet it happen, run cycle detection, then kill or roll back a victimDetection cost plus lost work
Ostrich algorithmIgnore it; reboot if necessaryWhat Windows, Linux and Unix actually do
Plain textBanker's algorithm — finding the safe sequence
Total resources: A=10 B=5 C=7 Allocation Max Need (Max - Allocation) A B C A B C A B C P0 0 1 0 7 5 3 7 4 3 P1 2 0 0 3 2 2 1 2 2 P2 3 0 2 9 0 2 6 0 0 P3 2 1 1 2 2 2 0 1 1 P4 0 0 2 4 3 3 4 3 1 Allocated = 7 2 5, so Available = 10-7, 5-2, 7-5 = 3 3 2 Walk it: Need(P1)=1 2 2 <= 3 3 2 -> run P1, release 2 0 0 -> Avail 5 3 2 Need(P3)=0 1 1 <= 5 3 2 -> run P3, release 2 1 1 -> Avail 7 4 3 Need(P4)=4 3 1 <= 7 4 3 -> run P4, release 0 0 2 -> Avail 7 4 5 Need(P0)=7 4 3 <= 7 4 5 -> run P0, release 0 1 0 -> Avail 7 5 5 Need(P2)=6 0 0 <= 7 5 5 -> run P2 Safe sequence: P1, P3, P4, P0, P2 -> the state is SAFE.

Memory management

The problem: give every process the illusion of a private, contiguous address space, while physical memory is shared, fragmented, and smaller than the sum of demands.

SchemeDivisionFragmentationNote
Contiguous, fixed partitionsMemory split into fixed blocksInternal — a process rarely fills its partition exactlySimple; wasteful
Contiguous, variable partitionsBlocks allocated to fitExternal — free space exists but is scatteredNeeds compaction
PagingFixed-size pages mapped to framesInternal only, at most one page per processNo external fragmentation at all — the key advantage
SegmentationVariable-size logical units: code, stack, heapExternalMatches the programmer's view; supports per-segment protection
Allocation strategyPicksBehaviour
First fitThe first hole large enoughFastest; good enough in practice
Best fitThe smallest hole large enoughWastes least per allocation but leaves many unusable slivers
Worst fitThe largest holeLeaves large usable remainders; performs poorly in practice

Paging mechanics

A logical address is split into a page number and an offset. The page number indexes the process's page table to find a frame number; the frame number and offset concatenate into the physical address. Because pages and frames are the same fixed size, any page fits any frame — which is exactly why external fragmentation disappears.

Virtual memory and page replacement

  1. Reference

    The CPU issues an address whose page-table entry has the valid bit clear.
  2. Trap

    The MMU raises a page fault, trapping to the OS. The faulting instruction is suspended.
  3. Locate

    The OS finds the page on the backing store and finds a free frame — running page replacement if none is free.
  4. Load

    The page is read into the frame. This is a disk I/O, so the process blocks and another is scheduled.
  5. Update and restart

    The page table is updated, the valid bit set, and the faulting instruction is restarted — not resumed midway.
Replacement algorithmEvictsBelady's anomaly?Note
FIFOThe oldest-loaded pageYesSimple; may evict a heavily used page
Optimal (OPT/MIN)The page used farthest in the futureNoUnimplementable — requires the future. Used as a benchmark
LRUThe least recently used pageNoGood approximation of OPT; costly to implement exactly
LFUThe least frequently used pageYesA page popular once then unused lingers forever
Clock (second chance)FIFO, but skip pages whose reference bit is setYesThe practical LRU approximation real kernels use
Plain textReference string 7,0,1,2,0,3,0,4 with 3 frames
FIFO LRU 7 -> [7] fault 7 -> [7] fault 0 -> [7,0] fault 0 -> [7,0] fault 1 -> [7,0,1] fault 1 -> [7,0,1] fault 2 -> [2,0,1] fault (7 out) 2 -> [2,0,1] fault (7 least recent) 0 -> [2,0,1] HIT 0 -> [2,0,1] HIT 3 -> [2,3,1] fault (0 out) 3 -> [2,0,3] fault (1 least recent) 0 -> [2,3,0] fault (1 out) 0 -> [2,0,3] HIT 4 -> [4,3,0] fault (2 out) 4 -> [4,0,3] fault (2 least recent) FIFO: 7 faults LRU: 6 faults LRU wins here because it keeps 0, which keeps being referenced.

Thrashing

Thrashing is the state where a process spends more time paging than executing. The mechanism is a feedback loop: high paging lowers CPU utilisation, so the scheduler admits more processes to raise utilisation, which reduces frames per process further, which increases paging. Utilisation collapses.

CureHow it works
Working set modelTrack the pages referenced in the last references. Give each process enough frames for its working set; suspend a process if the sum exceeds available frames
Page fault frequencyMeasure each process's fault rate directly. Above an upper bound, grant more frames; below a lower bound, take some away
Reduce multiprogrammingSwap whole processes out — counterintuitive, but the only way to break the loop

File systems and disk scheduling

Allocation methodHowSequential accessDirect accessWeakness
ContiguousConsecutive blocksExcellentExcellentExternal fragmentation; the file cannot grow
LinkedEach block points to the nextGoodPoor — O(n) to reach block nOne bad pointer loses the tail; per-block overhead
IndexedAn index block lists every data blockGoodExcellentIndex-block overhead; large files need multi-level indexes

The classic inode layout has twelve direct pointers, one single-indirect, one double-indirect and one triple-indirect. Small files are reached in a single lookup; large files remain addressable through the indirect levels.

Hard linkSymbolic (soft) link
Points toThe same inodeA path string
Survives deleting the originalYes — data lives until link count hits 0No — becomes a dangling link
Can cross filesystemsNoYes
Can link a directoryNo — it would allow cyclesYes
Consumes an extra inodeNoYes

Disk scheduling

AlgorithmBehaviourTrade-off
FCFSServe in arrival orderFair; a great deal of head movement
SSTFNearest request firstGood throughput; starves distant requests
SCAN (elevator)Sweep to one end, then reverseNo starvation; the edges wait longest
C-SCANSweep one way, jump back to the startMore uniform waiting time than SCAN
LOOK / C-LOOKAs SCAN/C-SCAN, but reverse at the last request rather than the disk edgeAvoids pointless travel to the platter edge

Self-check

12 questions on Operating Systems · nothing is stored

0/12 answered
Question 1

1.Which resource is shared between threads of the same process?

Question 2

2.Deadlock prevention works by:

Question 3

3.Belady's anomaly can occur with:

Question 4

4.The main advantage of paging over segmentation is that paging:

Question 5

5.The essential difference between a mutex and a binary semaphore is:

Question 6

6.A process whose I/O completes moves to which state?

Question 7

7.Thrashing is best remedied by:

Question 8

8.Which scheduling algorithm provably minimises average waiting time?

Question 9

9.With 4 KB pages and a 32-bit logical address, the page offset occupies how many bits?

Question 10

10.Deleting the original file breaks a symbolic link but not a hard link because:

Question 11

11.A system call transfers control to the kernel via:

Question 12

12.C-SCAN is preferred over SCAN mainly because it: