‹

05 · Operating Systems

EN

05 · Operating Systems

This chapter is the floor directly above the machine — where one processor is made to behave like a room full of them, and where the machine stops being something a program owns.

How does one machine pretend to be many, safely?

Between June 1985 and January 1987, six patients treated with a radiation machine called the Therac-25 received massive overdoses; at least three died. The machine was not broken in any way an engineer could see. Its predecessor had carried hardware interlocks — physical devices that made the dangerous configuration impossible — and on the Therac-25 they had been removed, because software would check instead. Nancy Leveson and Clark Turner found that the software checked, but that two of its concurrent tasks shared variables with no synchronization, so an operator typing quickly could change the treatment mode after the check had read it and before the hardware had finished moving (Leveson & Turner, IEEE Computer, July 1993). They also record what the machine was running on: "The system is not built using a standard operating system or executive. Rather, the real-time executive was written especially for the Therac-25" — by a single programmer, in assembly language, over several years.

That last sentence is the reason this chapter exists. An operating system is not a convenience layer. It is the accumulated answer to three problems lethal to solve again from scratch: how one machine is shared, how concurrent things stay coherent, and how anything survives being switched off. Remzi and Andrea Arpaci-Dusseau call them virtualization, concurrency, and persistence (Operating Systems: Three Easy Pieces). The unifying idea is that an operating system is a machine that lies, carefully: every service it offers is a falsehood about the floor below, maintained well enough to be relied on.

The first lie is arithmetic. Your laptop has a handful of processors and is running hundreds of programs, each written as though it had a machine to itself. The operating system multiplexes: it runs one program for a few milliseconds, saves every register, loads another's, and lets a hardware timer interrupt it so that no program can decline to give the machine back. The larger lie is about memory. The Atlas machine at Manchester, running in 1962, introduced a "one-level storage system": programs addressed a store far larger than physical memory, and hardware quietly moved pages between core and drum (Kilburn, Edwards, Lanigan & Sumner, 1962). Every process since has been handed the same fiction — virtual memory, as every descendant calls it: a private address space, starting at zero, that appears to be all its own. Two programs can both hold "address 4096" and never meet.

A lie is only safe if it cannot be inspected from inside; here the operating system depends on the floor below. The kernel is not privileged because it is cleverer than your program; it is privileged because the processor refuses certain instructions unless a mode bit is set. Multics defined eight such rings of protection; x86 inherited the idea with four, of which mainstream systems use two — kernel and user (Multics protection). Chapter 04's instruction set does not know what a process is; it knows only that some instructions are forbidden in the outer mode, and that attempting one traps. Everything about isolation, security, and multi-tenancy is built from that single hardware gesture.

The second problem, concurrency, is the one that killed the Therac patients. Once two things run at once and touch the same data, correctness stops being a property of either one alone. Edsger Dijkstra gave the field its basic tool in 1965, the semaphore, in notes titled "Cooperating Sequential Processes", and used it to build the layered THE system (CACM, May 1968). But mutual exclusion trades one failure for another: a process holding one lock while waiting for a second can wait forever. Coffman, Elphick and Shoshani named the four conditions that must all hold for deadlock — mutual exclusion, hold-and-wait, no preemption, and circular wait — in ACM Computing Surveys in 1971 (System Deadlocks). Break any one and deadlock is impossible; that is still how it is handled. Notice what the operating system offers: not a removal of the difficulty but primitives correct enough to build on. The honest reading of the Therac-25 is that an engineer who declines them is re-deriving 1965 alone, under deadline.

The third lie is that storage remembers. It does — but power can be cut between any two instructions, including the two that would have left the disk in a sensible state. The operating system's answer is fsync, which returns only when data has reached the device, and file systems that journal their intentions, so a half-finished operation can be replayed or undone. The abstraction leaks badly: fsync on a new file does not make the file's directory entry durable — you must sync the parent directory too. When Pillai and colleagues checked how eleven widely used applications behaved across crashes, they found sixty distinct crash vulnerabilities (All File Systems Are Not Created Equal, OSDI 2014). These were not amateur programs. The surface says "saved," and only the floor below knows whether that is true.

One design rule holds the whole thing together: separate mechanism from policy. The kernel supplies the machinery to do a thing and leaves the decision of what to do to whoever is above it. Hydra stated it as a design principle in 1974 (Wulf et al., CACM 17, no. 6), and Butler Lampson's "Hints for Computer System Design" made it common sense by 1983. The reason is simple: policy changes far faster than mechanism, and a kernel that bakes in a scheduling preference or a security model must be rewritten when opinion moves. The interface that results is astonishingly narrow for what it carries: the x86-64 system call table in the current Linux source lists 385 entries (kernel source, checked 1 August 2026). Everything you have ever run passed through that door.

The people here inherited each other directly. Fernando Corbató demonstrated the Compatible Time-Sharing System at MIT in 1961 and then led Multics, whose ambition was computing sold like electricity — a utility, always on, shared by strangers. Bell Labs pulled out in 1969, and Dennis Ritchie's account of what followed is unglamorous: the Labs refused to buy a replacement machine, so "it did not take long, therefore, for Thompson to find a little-used PDP-7" (Ritchie, The Evolution of the Unix Time-sharing System). Ken Thompson wrote the first Unix on it in about a month, in the summer of 1969, while his wife was away — "essentially one person for a month, it was just myself," he said later (oral history, 1989). Multics tried to specify everything; Unix was small because it had no budget to be large, and the small one spread. Thompson and Ritchie received the Turing Award in 1983, Corbató in 1990.

Connections

Below is 04, which supplies everything that makes the illusion enforceable: privileged mode, the timer interrupt, and address-translation hardware. Above it, 06 compiles programs against the process abstraction described here. Chapter 07 carries the same instinct upward — hide the decision that will change, publish only the interface — and chapter 08 is largely the story of one application refusing to trust this floor's persistence guarantees and rebuilding them itself. Chapter 10 asks what happens to all of this when the "one machine" is a thousand of them, and chapter 11 treats the kernel boundary as the line an attacker is trying to cross.

Open questions

Is the kernel still the right place for the boundary? Microkernels, unikernels, and in-kernel virtual machines each move the line, and none has settled the argument. The process abstraction was designed for a machine whose interesting hardware was the CPU; today much of the work happens on accelerators the kernel barely schedules. And why, after sixty years, is concurrency still where careful engineers are most likely to be wrong?

Go deeper

บทถัดไป · 7 / 1606 · Languages & Compilers
Size
Page
Font

The Tower of Abstractions — An Encyclopedia of the Computing Disciplines

❦
100 · The Map201 · Theory of Computation302 · Algorithms & Data Structures403 · Information & Coding504 · Computer Architecture605 · Operating Systems706 · Languages & Compilers807 · Software Engineering908 · Databases1009 · Networks1110 · Distributed Systems1211 · Security & Cryptography1312 · AI & Machine Learning1413 · HCI & Graphics1514 · The Frontier1699 · Closing — The Tower, Seen Whole