17. Midterm Review¶
This week is midterm exam week — there is no new topic to learn today. Instead, this chapter is a checkpoint: a condensed tour of everything covered in Lectures 1–16, from what an operating system actually is through the classical synchronization problems that make concurrent code so easy to get subtly wrong. Four units got you here — OS Structure and Design, Process Management with IPC and Threads, CPU Scheduling, and Process Synchronization — and the exam draws from all four. Use this lecture to check which ideas feel solid and which need another pass before you sit down to write.
In This Lecture¶
- Consolidate your understanding of OS structure, the process concept, and the role of the kernel
- Compare every CPU scheduling algorithm covered so far, side by side, in one table
- Review the synchronization tools used to protect shared data, and when each one applies
- Revisit the classical synchronization problems and what each one is designed to test
- Self-test your recall with a short, answer-free quiz before the exam
Concept Map¶
Each unit hands the next one a vocabulary it assumes fluency with. Unit 1 gives you the operating system itself and the boundary between user mode and kernel mode; Unit 2 gives you the process — the thing the OS actually schedules and synchronizes; Unit 3 decides which ready process gets the CPU next; Unit 4 is what keeps processes that share data from corrupting it while they wait their turn.
Lectures 1–16, four units
Unit 1: OS Structure & Design What an OS does, kernel designs, system calls, user/kernel mode
Unit 2: Processes, IPC & Threads Process states, the PCB, context switches, shared memory vs. message passing, threading models
Unit 3: CPU Scheduling Scheduling criteria, FCFS, SJF, Priority, Round Robin, multilevel queues
Unit 4: Process Synchronization Critical sections, semaphores, monitors, Producer-Consumer, Readers-Writers, Dining Philosophers
Notice the dependency runs in one direction: you cannot reason about scheduling (Unit 3) without first knowing what a process is and what state it can be in (Unit 2), and you cannot reason about synchronization (Unit 4) without accepting that scheduling means processes genuinely do interleave in ways you don't fully control. Nothing here is re-taught after this point — only re-applied, starting with deadlocks in Lecture 19.
Unit 1: OS Structure & Design — What You Must Remember¶
An operating system is the layer of software that manages hardware on behalf of every running program, exposing a controlled set of system calls as the only legal way for a user program to request a privileged operation. The mode bit is what makes this enforceable: user mode restricts what an instruction stream is allowed to touch directly, and only a trap into kernel mode — triggered by a system call, an interrupt, or an exception — lets the CPU execute privileged instructions on the program's behalf.
Kernel designs trade off isolation against communication cost, and this trade-off is exactly what distinguishes them:
| Kernel design | How it's organized | Trade-off |
|---|---|---|
| Monolithic | Nearly everything (drivers, file system, scheduler) runs in one kernel address space | Fast — one function call, no context switch — but one bad driver can crash the entire system |
| Layered | Strict layers, each built only on the layer below it | Easier to debug and reason about; still one address space |
| Microkernel | Only the bare minimum (IPC, basic scheduling, memory management) runs in kernel mode; everything else runs as a user-mode server | Most crash-resilient — a failing server can be restarted — but every service request now costs a message, not a function call |
| Hybrid | A small trusted core plus selected subsystems still running in kernel mode for speed | Most real production OSes (Windows, macOS/XNU, modern Linux with loadable modules) land here, not at either pure extreme |
If an exam question says 'crashes the whole system,' think monolithic
The fastest way to tell these apart on an exam is to ask what happens when one component fails. A monolithic kernel's components share one address space and one fault domain — a bug anywhere can bring down everything. A microkernel's servers are isolated processes; a crash is contained and often recoverable.
Unit 2: Processes, IPC & Threads — What You Must Remember¶
A process is a program in execution, tracked by the OS through its Process Control Block (PCB) — process state, program counter, CPU registers, memory limits, and I/O status. A process moves between five states (new, ready, running, waiting, terminated), and every transition between them is driven by the scheduler, an interrupt, or an I/O event — a process never changes its own state unilaterally.
A thread is the actual unit the CPU executes; a process is the container that owns the address space one or more threads share. Switching between threads of the same process is far cheaper than switching between processes, because the address space, open files, and most of the PCB don't need to change — only the per-thread register set and stack pointer do.
IPC: two fundamentally different strategies
Shared memory Processes read/write a region both can see directly — fast, but every access must be synchronized by the programmer (Unit 4's entire subject)
Message passing Processes exchange explicit send()/receive() messages through the kernel — slower (a kernel trap per message), but synchronization comes nearly for free
Threading models describe how user-level threads map onto kernel-schedulable threads: many-to-one multiplexes many user threads onto a single kernel thread (cheap to create, but one blocking system call freezes every thread, and true parallelism across cores is impossible since the kernel only ever sees one schedulable entity); one-to-one maps each user thread to its own kernel thread (true parallelism, at the cost of a kernel-level context switch per thread); many-to-many multiplexes many user threads onto a smaller or equal pool of kernel threads, trying to capture the cheapness of the first model and the parallelism of the second.
Unit 3: CPU Scheduling — What You Must Remember¶
The scheduler's job is to pick which ready process gets the CPU next, judged against several criteria at once: CPU utilization, throughput, turnaround time, waiting time, and response time — and these criteria often pull in different directions, which is exactly why no single algorithm dominates every workload.
| Algorithm | Preemptive? | Avg. Wait Time Optimality | Starvation Risk | Real-World Use |
|---|---|---|---|---|
| FCFS | No | Poor — one long job at the front causes a convoy effect for everyone behind it | None (strict first-in, first-out order) | Simple batch queues; almost never used alone |
| SJF (non-preemptive) | No | Optimal among non-preemptive algorithms, for a fixed, known batch of jobs | High — a long job can be pushed back indefinitely by a steady stream of shorter arrivals | Batch systems where burst times can be estimated in advance |
| SRTF (preemptive SJF) | Yes | Optimal overall — the lowest achievable average waiting time | High — same risk as SJF, sharpened by constant preemption | Rare in practice; mainly a theoretical lower bound to compare against |
| Priority Scheduling | Either | Not inherently optimal — entirely dependent on how priorities are assigned | High for low-priority processes, unless mitigated by aging | The underlying mechanism inside most general-purpose schedulers |
| Round Robin | Yes | Moderate — governed almost entirely by the time-quantum size | None — every process cycles through the ready queue in turn | Time-sharing and interactive systems; the default fairness building block |
| Multilevel Queue | Usually | Depends on the fixed priority given to each queue | Possible for lower queues if higher-priority queues never empty out | Separating batch workloads from interactive ones |
| Multilevel Feedback Queue | Yes | Good in practice — adapts to a process's observed CPU-vs-I/O behavior | Low — processes can migrate toward higher-priority queues over time | Closest conceptual model to real general-purpose OS schedulers |
The quantum size is Round Robin's entire personality
A time quantum that's too large makes Round Robin degrade toward FCFS behavior (each process nearly runs to completion before preemption). A quantum that's too small makes context-switch overhead dominate actual useful work. The "right" quantum is a tuning problem, not a fixed constant — this is precisely why multilevel feedback queues exist: they let the system adapt the effective quantum per process instead of fixing one value for everyone.
Unit 4: Process Synchronization — What You Must Remember¶
A race condition occurs when the outcome of concurrent execution depends on the precise timing of interleaved operations on shared data. The critical-section problem asks for a protocol around the shared-data access that guarantees three properties simultaneously: mutual exclusion (only one process in its critical section at a time), progress (if no process is in its critical section, one of the processes wanting in must eventually be allowed to enter — the decision can't stall forever), and bounded waiting (a process cannot be made to wait an unbounded number of turns while others repeatedly cut in line).
Semaphores generalize the lock into an integer, manipulated only through wait()
(decrement, block if the result would go negative) and signal() (increment, wake a waiting
process if one exists) — a binary semaphore behaves like a mutex lock; a counting
semaphore controls access to a pool of several identical resources. Monitors package a
lock together with the shared data and the only operations allowed to touch it, so the
programmer cannot forget to call wait()/signal() in the right place — the compiler
enforces it structurally instead.
The three classical synchronization problems, condensed
Producer–Consumer Bounded buffer; tests coordinating a count (empty/full slots) alongside mutual exclusion over the buffer itself
Readers–Writers Many readers may overlap safely; a writer needs total exclusivity — tests asymmetric access rules
Dining Philosophers Circular resource acquisition (forks); tests exactly the kind of cyclic waiting that causes deadlock
Dining Philosophers is a preview, not just a puzzle
Each philosopher trying to pick up both neighboring forks is a direct, physical model of a circular-wait: every philosopher holds one resource while waiting for another, held by the next philosopher around the table. If every philosopher picks up their left fork first, the table can deadlock completely. Lecture 19 names this pattern formally and gives you a vocabulary — hold-and-wait, circular wait — for exactly what goes wrong here.
Key Takeaways¶
- The four units build on each other in one direction: structure and processes (Units 1–2) are what the scheduler (Unit 3) chooses among, and scheduling is why synchronization (Unit 4) is necessary at all — interleaving is a real, unavoidable consequence of letting a scheduler pick when each process runs.
- Kernel design is a trade-off between speed (monolithic) and fault isolation (microkernel); most real systems are hybrids.
- Threads share an address space and are cheaper to switch between than processes; many-to-one threading cannot achieve parallelism on a multicore machine no matter how many user threads exist, because the kernel only ever schedules one of them at a time.
- No scheduling algorithm wins on every criterion at once — know the preemption, optimality, and starvation trade-offs in the table above cold.
- The critical-section problem's three requirements — mutual exclusion, progress, bounded waiting — are the yardstick every synchronization tool (locks, semaphores, monitors) is judged against.
- The three classical problems each isolate a different failure mode: counting shared slots (Producer–Consumer), asymmetric access (Readers–Writers), and circular waiting (Dining Philosophers) — the last of which is exactly where deadlock, starting Lecture 19, picks up.
Self-Test¶
Check yourself
These questions have no answers printed below them on purpose — they're for self-assessment before the exam, not for re-reading a solution. Work through each one on paper; if you get stuck, that's the lecture to revisit.
- Why does a microkernel improve fault isolation over a monolithic kernel, and what does it give up in exchange?
- State the three requirements a correct critical-section solution must satisfy, and explain, in one sentence each, what would go wrong if one of them were violated.
-
A single CPU system has four processes with the arrival and burst times below. Compute the Gantt chart and the average waiting time under non-preemptive SJF.
Process Arrival Time Burst Time P1 0 6 P2 2 2 P3 4 1 P4 5 4 -
Why can Round Robin's performance degrade toward FCFS if the time quantum is too large, and toward excessive overhead if it is too small?
- A binary semaphore
mutexis initialized to 1. Three processes each executewait(mutex)in quick succession, with no correspondingsignal(mutex)call in between. What is the state of each of the three processes, and what is the final value ofmutex? - Explain, using your own words, how the Dining Philosophers problem models hold-and-wait and circular wait at the same time.
- Distinguish a process from a thread in terms of what each one owns, and explain why a context switch between two threads of the same process is cheaper than a context switch between two unrelated processes.
- Why is non-preemptive SJF described as "optimal among non-preemptive algorithms" rather than simply "optimal"? What algorithm, if any, beats it — and at what cost?
Lecture 18 turns this review into deliberate practice: four fully worked problems built to mirror exactly the kind of question this midterm — and the final — will ask. Head there next: Lecture 18: Problem-Solving Workshop: Scheduling and Synchronization.