Input/Output Systems

I/O is the part of an operating system that sits closest to the hardware, and it is also the part most often underestimated. This chapter starts from a simple question — how different are devices from one another — and ends with another: which layers does a single read request actually pass through?

The first question concerns the devices themselves. Devices can be classified by the way they exchange information, by transfer speed, and by function, and each one has its own transfer, control, and reliability characteristics. Because those differences exist, one generic strategy will not do: the system needs classification, scheduling, and buffering instead.

The second question concerns how the CPU gives up control. Programmed I/O leaves the CPU waiting; interrupt-driven I/O lets the device raise a notification; DMA hands an entire block over to a controller. The differences among the three in overhead, parallelism, and complexity decide which one belongs in a given situation.

The third question concerns how resources are organized and protected. Device drivers hide hardware details, static, dynamic, and shared allocation policies answer different exclusivity and sharing needs, and error detection and recovery keep a single failure from spreading into a system-wide crash.

The fourth question concerns throughput. Single, double, and multiple buffering absorb the speed gap between device and CPU; buffer scheduling policies, together with memory, cache, and concurrency optimizations, push latency down further; the I/O subsystem strings these pieces into a complete hierarchy, and asynchronous I/O and I/O multiplexing are the key tools of a modern system.

By the end of this chapter you should be able to explain where each of the three I/O control methods fits, compare the trade-offs of the three buffering schemes, and name the layers a single I/O request passes through in a typical I/O subsystem.

Chapters

Found an issue with this content?

Tell us what could be improved.