This is an HTML rendering of a working paper draft that led to a publication. The publication should always be cited in preference to this draft using the following reference:

The document's metadata is available in BibTeX format.

This material is presented to ensure timely dissemination of scholarly and technical work. Copyright and all rights therein are retained by authors or by other copyright holders. All persons copying this information are expected to adhere to the terms and constraints invoked by each author's copyright. In most cases, these works may not be reposted without the explicit permission of the copyright holder.

Diomidis Spinellis Publications

Copyright © 2010 by the Association for Computing Machinery, Inc. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from Publications Dept, ACM Inc., fax +1 (212) 869-0481, or

Book Review: Principles of Computer System Design: An Introduction

Diomidis Spinellis
Athens University of Economics and Business

Saltzer J., Kaashoek M.
Principles of Computer System Design: An Introduction
Morgan Kaufmann Publishers Inc., San Francisco, CA, 2009.
576 pp

On a shelf behind my back I keep a set of classic authoritative books, which I consult often when I work. Saltzer and Frans Kaashoek’s “Principles of Computer System Design” clearly belongs to this shelf.

The book starts with an overview of systems and the four techniques we employ to cope with their complexity: modularity, abstraction layering, and hierarchy. It then details the elements of computer system organization through the three fundamental abstractions of memory, interpreters, and communication links. Subsequent chapters cover the design of naming schemes, the enforcement of modularity through the division of work between clients and services and through virtualization, and performance optimization. According to the authors, these topics cover the subject’s core material. Further, more specialized, chapters on networks, fault tolerance, atomicity, consistency, and information security are provided on-line.

The ideas presented in this book are timeless classics, but the clear perspective on offer is sometimes refreshingly novel. Examples include the presentation of name overloading, the view of encryption keys as names from a large and sparsely populated name space, the discussion of virtualization in terms of multiplexing, aggregation, and emulation, and a candid argument for monolithic kernels. The authors also document elements of the practitioner community’s tacit knowledge, such as the principle of least astonishment, the layer bypass optimization technique, and the reason why Unix filesystems prohibit hard links between directories.

The text is illustrated through many clearly-drawn diagrams, although I would have preferred them drawn in a standard notation, like UML. Particularly disconcerting was the use of the term “timing diagram” for what is commonly known as a sequence diagram. Entertaining war stories, like the one describing problems of zip code renumbering, and detailed case studies such as those of Unix, NFS, and Intel architectures, provide relevance and document succinctly some classic computer systems. The book contains many clever and interesting exercises, a number of larger problems sets, and a rare case of an annotated bibliography that is actually a joy to read. Some may even consider the list of 25 design principles and four design hints on the inside of the front cover worth the entire book’s price.

From a pedagogical perspective it is sometimes unclear whether the book targets beginners or graduate students. An example on p. 68 requires the understanding of page map registers, while ten pages later one of the many excellent sidebars introduces the concept of an operating system. A wider question is whether system design principles can actually be taught, even from this magnificent book, or they can only be learned over many years from the detailed study of actual systems and bucketfuls of design and implementation experience. Yet, computer science education can surely benefit from this work, if professors read it and reorient their lectures toward the presentation of their course’s underlying principles.

Both authors are pioneering operating system researchers, and their interests sometimes seem to bias the choice of a chapter’s topics. For instance, the chapter on performance discusses page replacement and scheduling policies at length, while failing to address the equally important topics of algorithmic complexity and space utilization. Similarly, although the authors list interpreters as one of the three fundamental computer system abstractions, these receive far less attention than memory and communication links. This slant makes the work an excellent and innovative textbook for a modern operating systems course, and a trailblazing though slightly unbalanced attempt to lay out and organize the foundations of computer systems discourse.