100% found this document useful (2 votes)
24 views

Operating systems and middleware supporting controlled interaction Max Hailperin pdf download

The document is a comprehensive guide to operating systems and middleware, focusing on controlled interaction between computations. It covers essential topics such as threads, scheduling, synchronization, atomic transactions, and virtual memory. The work is authored by Max Hailperin and is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.

Uploaded by

beamsalberw1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
24 views

Operating systems and middleware supporting controlled interaction Max Hailperin pdf download

The document is a comprehensive guide to operating systems and middleware, focusing on controlled interaction between computations. It covers essential topics such as threads, scheduling, synchronization, atomic transactions, and virtual memory. The work is authored by Max Hailperin and is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.

Uploaded by

beamsalberw1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 75

Operating systems and middleware supporting

controlled interaction Max Hailperin download

https://ebookgate.com/product/operating-systems-and-middleware-
supporting-controlled-interaction-max-hailperin/

Get Instant Ebook Downloads – Browse at https://ebookgate.com


Get Your Digital Files Instantly: PDF, ePub, MOBI and More
Quick Digital Downloads: PDF, ePub, MOBI and Other Formats

Computer Systems An Integrated Approach to Architecture


and Operating Systems Umakishore Ramachandran

https://ebookgate.com/product/computer-systems-an-integrated-
approach-to-architecture-and-operating-systems-umakishore-
ramachandran/

Operating Systems Design and Implementation 3rd Edition


Andrew S. Tanenbaum

https://ebookgate.com/product/operating-systems-design-and-
implementation-3rd-edition-andrew-s-tanenbaum/

Operating systems internals and design principles 7th


ed Edition Stallings

https://ebookgate.com/product/operating-systems-internals-and-
design-principles-7th-ed-edition-stallings/

Operating Systems A Spiral Approach 1st Edition Ramez


Elmasri

https://ebookgate.com/product/operating-systems-a-spiral-
approach-1st-edition-ramez-elmasri/
Advanced Concepts in Operating Systems Indian Edition
Mukesh Singhal

https://ebookgate.com/product/advanced-concepts-in-operating-
systems-indian-edition-mukesh-singhal/

Advanced Operating Systems and Kernel Applications


Techniques and Technologies 1st Edition Yair Wiseman

https://ebookgate.com/product/advanced-operating-systems-and-
kernel-applications-techniques-and-technologies-1st-edition-yair-
wiseman/

Operating Systems Principles and Practice Vol 3 Memory


Management 2nd Edition Thomas Anderson

https://ebookgate.com/product/operating-systems-principles-and-
practice-vol-3-memory-management-2nd-edition-thomas-anderson/

The Handbook of Mobile Middleware 1st Edition Paolo


Bellavista

https://ebookgate.com/product/the-handbook-of-mobile-
middleware-1st-edition-paolo-bellavista/

Data hiding Exposing concealed data in multimedia


operating systems mobile devices and network protocols
1st Edition Michael T. Raggo

https://ebookgate.com/product/data-hiding-exposing-concealed-
data-in-multimedia-operating-systems-mobile-devices-and-network-
protocols-1st-edition-michael-t-raggo/
Operating Systems and Middleware:
Supporting Controlled Interaction

Max Hailperin
Gustavus Adolphus College

Revised Edition 1.1.1


August 8, 2011
Copyright c 2011 by Max Hailperin.

This work is licensed under the Creative Commons Attribution-ShareAlike


3.0 Unported License. To view a copy of this license, visit

http:// creativecommons.org/ licenses/ by-sa/ 3.0/

or send a letter to Creative Commons, 171 Second Street, Suite 300, San
Francisco, California, 94105, USA.
To my family
iv
Contents

Preface xi

1 Introduction 1
1.1 Chapter Overview . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 What Is an Operating System? . . . . . . . . . . . . . . . . . 2
1.3 What is Middleware? . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 Objectives for the Book . . . . . . . . . . . . . . . . . . . . . 8
1.5 Multiple Computations on One Computer . . . . . . . . . . . 9
1.6 Controlling the Interactions Between Computations . . . . . . 11
1.7 Supporting Interaction Across Time . . . . . . . . . . . . . . 13
1.8 Supporting Interaction Across Space . . . . . . . . . . . . . . 15
1.9 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2 Threads 21
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Example of Multithreaded Programs . . . . . . . . . . . . . . 23
2.3 Reasons for Using Concurrent Threads . . . . . . . . . . . . . 27
2.4 Switching Between Threads . . . . . . . . . . . . . . . . . . . 30
2.5 Preemptive Multitasking . . . . . . . . . . . . . . . . . . . . . 37
2.6 Security and Threads . . . . . . . . . . . . . . . . . . . . . . . 38

3 Scheduling 45
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.2 Thread States . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.3 Scheduling Goals . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.3.1 Throughput . . . . . . . . . . . . . . . . . . . . . . . . 51
3.3.2 Response Time . . . . . . . . . . . . . . . . . . . . . . 54
3.3.3 Urgency, Importance, and Resource Allocation . . . . 55
3.4 Fixed-Priority Scheduling . . . . . . . . . . . . . . . . . . . . 61

v
vi CONTENTS

3.5 Dynamic-Priority Scheduling . . . . . . . . . . . . . . . . . . 65


3.5.1 Earliest Deadline First Scheduling . . . . . . . . . . . 65
3.5.2 Decay Usage Scheduling . . . . . . . . . . . . . . . . . 66
3.6 Proportional-Share Scheduling . . . . . . . . . . . . . . . . . 71
3.7 Security and Scheduling . . . . . . . . . . . . . . . . . . . . . 79

4 Synchronization and Deadlocks 93


4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
4.2 Races and the Need for Mutual Exclusion . . . . . . . . . . . 95
4.3 Mutexes and Monitors . . . . . . . . . . . . . . . . . . . . . . 98
4.3.1 The Mutex Application Programing Interface . . . . . 99
4.3.2 Monitors: A More Structured Interface to Mutexes . . 103
4.3.3 Underlying Mechanisms for Mutexes . . . . . . . . . . 106
4.4 Other Synchronization Patterns . . . . . . . . . . . . . . . . . 110
4.4.1 Bounded Buffers . . . . . . . . . . . . . . . . . . . . . 113
4.4.2 Readers/Writers Locks . . . . . . . . . . . . . . . . . . 115
4.4.3 Barriers . . . . . . . . . . . . . . . . . . . . . . . . . . 116
4.5 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . 117
4.6 Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
4.7 Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
4.7.1 The Deadlock Problem . . . . . . . . . . . . . . . . . . 126
4.7.2 Deadlock Prevention Through Resource Ordering . . . 128
4.7.3 Ex Post Facto Deadlock Detection . . . . . . . . . . . 129
4.7.4 Immediate Deadlock Detection . . . . . . . . . . . . . 132
4.8 The Interaction of Synchronization with Scheduling . . . . . . 134
4.8.1 Priority Inversion . . . . . . . . . . . . . . . . . . . . . 135
4.8.2 The Convoy Phenomenon . . . . . . . . . . . . . . . . 137
4.9 Nonblocking Synchronization . . . . . . . . . . . . . . . . . . 141
4.10 Security and Synchronization . . . . . . . . . . . . . . . . . . 145

5 Atomic Transactions 159


5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
5.2 Example Applications of Transactions . . . . . . . . . . . . . 162
5.2.1 Database Systems . . . . . . . . . . . . . . . . . . . . 163
5.2.2 Message-Queuing Systems . . . . . . . . . . . . . . . . 167
5.2.3 Journaled File Systems . . . . . . . . . . . . . . . . . 172
5.3 Mechanisms to Ensure Atomicity . . . . . . . . . . . . . . . . 174
5.3.1 Serializability: Two-Phase Locking . . . . . . . . . . . 174
5.3.2 Failure Atomicity: Undo Logging . . . . . . . . . . . . 183
5.4 Transaction Durability: Write-Ahead Logging . . . . . . . . . 186
CONTENTS vii

5.5 Additional Transaction Mechanisms . . . . . . . . . . . . . . 190


5.5.1 Increased Transaction Concurrency: Reduced Isolation 191
5.5.2 Coordinated Transaction Participants: Two-Phase Com-
mit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
5.6 Security and Transactions . . . . . . . . . . . . . . . . . . . . 196

6 Virtual Memory 207


6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
6.2 Uses for Virtual Memory . . . . . . . . . . . . . . . . . . . . . 212
6.2.1 Private Storage . . . . . . . . . . . . . . . . . . . . . . 212
6.2.2 Controlled Sharing . . . . . . . . . . . . . . . . . . . . 213
6.2.3 Flexible Memory Allocation . . . . . . . . . . . . . . . 216
6.2.4 Sparse Address Spaces . . . . . . . . . . . . . . . . . . 219
6.2.5 Persistence . . . . . . . . . . . . . . . . . . . . . . . . 219
6.2.6 Demand-Driven Program Loading . . . . . . . . . . . 220
6.2.7 Efficient Zero Filling . . . . . . . . . . . . . . . . . . . 221
6.2.8 Substituting Disk Storage for RAM . . . . . . . . . . 222
6.3 Mechanisms for Virtual Memory . . . . . . . . . . . . . . . . 223
6.3.1 Software/Hardware Interface . . . . . . . . . . . . . . 225
6.3.2 Linear Page Tables . . . . . . . . . . . . . . . . . . . . 229
6.3.3 Multilevel Page Tables . . . . . . . . . . . . . . . . . . 234
6.3.4 Hashed Page Tables . . . . . . . . . . . . . . . . . . . 239
6.3.5 Segmentation . . . . . . . . . . . . . . . . . . . . . . . 242
6.4 Policies for Virtual Memory . . . . . . . . . . . . . . . . . . . 247
6.4.1 Fetch Policy . . . . . . . . . . . . . . . . . . . . . . . . 248
6.4.2 Placement Policy . . . . . . . . . . . . . . . . . . . . . 250
6.4.3 Replacement Policy . . . . . . . . . . . . . . . . . . . 252
6.5 Security and Virtual Memory . . . . . . . . . . . . . . . . . . 259

7 Processes and Protection 269


7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
7.2 POSIX Process Management API . . . . . . . . . . . . . . . . 271
7.3 Protecting Memory . . . . . . . . . . . . . . . . . . . . . . . . 281
7.3.1 The Foundation of Protection: Two Processor Modes 282
7.3.2 The Mainstream: Multiple Address Space Systems . . 285
7.3.3 An Alternative: Single Address Space Systems . . . . 287
7.4 Representing Access Rights . . . . . . . . . . . . . . . . . . . 289
7.4.1 Fundamentals of Access Rights . . . . . . . . . . . . . 289
7.4.2 Capabilities . . . . . . . . . . . . . . . . . . . . . . . . 295
7.4.3 Access Control Lists and Credentials . . . . . . . . . . 299
viii CONTENTS

7.5 Alternative Granularities of Protection . . . . . . . . . . . . . 307


7.5.1 Protection Within a Process . . . . . . . . . . . . . . . 308
7.5.2 Protection of Entire Simulated Machines . . . . . . . . 309
7.6 Security and Protection . . . . . . . . . . . . . . . . . . . . . 313

8 Files and Other Persistent Storage 329


8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
8.2 Disk Storage Technology . . . . . . . . . . . . . . . . . . . . . 332
8.3 POSIX File API . . . . . . . . . . . . . . . . . . . . . . . . . 336
8.3.1 File Descriptors . . . . . . . . . . . . . . . . . . . . . . 336
8.3.2 Mapping Files Into Virtual Memory . . . . . . . . . . 341
8.3.3 Reading and Writing Files at Specified Positions . . . 344
8.3.4 Sequential Reading and Writing . . . . . . . . . . . . 344
8.4 Disk Space Allocation . . . . . . . . . . . . . . . . . . . . . . 346
8.4.1 Fragmentation . . . . . . . . . . . . . . . . . . . . . . 347
8.4.2 Locality . . . . . . . . . . . . . . . . . . . . . . . . . . 350
8.4.3 Allocation Policies and Mechanisms . . . . . . . . . . 352
8.5 Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
8.5.1 Data Location Metadata . . . . . . . . . . . . . . . . . 355
8.5.2 Access Control Metadata . . . . . . . . . . . . . . . . 364
8.5.3 Other Metadata . . . . . . . . . . . . . . . . . . . . . 367
8.6 Directories and Indexing . . . . . . . . . . . . . . . . . . . . . 367
8.6.1 File Directories Versus Database Indexes . . . . . . . . 367
8.6.2 Using Indexes to Locate Files . . . . . . . . . . . . . . 369
8.6.3 File Linking . . . . . . . . . . . . . . . . . . . . . . . . 370
8.6.4 Directory and Index Data Structures . . . . . . . . . . 374
8.7 Metadata Integrity . . . . . . . . . . . . . . . . . . . . . . . . 375
8.8 Polymorphism in File System Implementations . . . . . . . . 379
8.9 Security and Persistent Storage . . . . . . . . . . . . . . . . . 380

9 Networking 391
9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
9.1.1 Networks and Internets . . . . . . . . . . . . . . . . . 392
9.1.2 Protocol Layers . . . . . . . . . . . . . . . . . . . . . . 394
9.1.3 The End-to-End Principle . . . . . . . . . . . . . . . . 397
9.1.4 The Networking Roles of Operating Systems, Middle-
ware, and Application Software . . . . . . . . . . . . . 398
9.2 The Application Layer . . . . . . . . . . . . . . . . . . . . . . 399
9.2.1 The Web as a Typical Example . . . . . . . . . . . . . 399
CONTENTS ix

9.2.2 The Domain Name System: Application Layer as In-


frastructure . . . . . . . . . . . . . . . . . . . . . . . . 402
9.2.3 Distributed File Systems: An Application Viewed Through
Operating Systems . . . . . . . . . . . . . . . . . . . . 405
9.3 The Transport Layer . . . . . . . . . . . . . . . . . . . . . . . 407
9.3.1 Socket APIs . . . . . . . . . . . . . . . . . . . . . . . . 408
9.3.2 TCP, the Dominant Transport Protocol . . . . . . . . 414
9.3.3 Evolution Within and Beyond TCP . . . . . . . . . . 417
9.4 The Network Layer . . . . . . . . . . . . . . . . . . . . . . . . 418
9.4.1 IP, Versions 4 and 6 . . . . . . . . . . . . . . . . . . . 418
9.4.2 Routing and Label Switching . . . . . . . . . . . . . . 421
9.4.3 Network Address Translation: An End to End-to-End? 422
9.5 The Link and Physical Layers . . . . . . . . . . . . . . . . . . 425
9.6 Network Security . . . . . . . . . . . . . . . . . . . . . . . . . 427
9.6.1 Security and the Protocol Layers . . . . . . . . . . . . 428
9.6.2 Firewalls and Intrusion Detection Systems . . . . . . . 430
9.6.3 Cryptography . . . . . . . . . . . . . . . . . . . . . . . 431

10 Messaging, RPC, and Web Services 443


10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
10.2 Messaging Systems . . . . . . . . . . . . . . . . . . . . . . . . 444
10.3 Remote Procedure Call . . . . . . . . . . . . . . . . . . . . . 447
10.3.1 Principles of Operation for RPC . . . . . . . . . . . . 448
10.3.2 An Example Using Java RMI . . . . . . . . . . . . . . 451
10.4 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
10.5 Security and Communication Middleware . . . . . . . . . . . 463

11 Security 473
11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
11.2 Security Objectives and Principles . . . . . . . . . . . . . . . 474
11.3 User Authentication . . . . . . . . . . . . . . . . . . . . . . . 480
11.3.1 Password Capture Using Spoofing and Phishing . . . . 481
11.3.2 Checking Passwords Without Storing Them . . . . . . 483
11.3.3 Passwords for Multiple, Independent Systems . . . . . 483
11.3.4 Two-Factor Authentication . . . . . . . . . . . . . . . 483
11.4 Access and Information-Flow Controls . . . . . . . . . . . . . 486
11.5 Viruses and Worms . . . . . . . . . . . . . . . . . . . . . . . . 491
11.6 Security Assurance . . . . . . . . . . . . . . . . . . . . . . . . 495
11.7 Security Monitoring . . . . . . . . . . . . . . . . . . . . . . . 497
11.8 Key Security Best Practices . . . . . . . . . . . . . . . . . . . 500
x CONTENTS

A Stacks 511
A.1 Stack-Allocated Storage: The Concept . . . . . . . . . . . . . 512
A.2 Representing a Stack in Memory . . . . . . . . . . . . . . . . 513
A.3 Using a Stack for Procedure Activations . . . . . . . . . . . . 514

Bibliography 517
Preface

Suppose you sit down at your computer to check your email. One of the
messages includes an attached document, which you are to edit. You click
the attachment, and it opens up in another window. After you start edit-
ing the document, you realize you need to leave for a trip. You save the
document in its partially edited state and shut down the computer to save
energy while you are gone. Upon returning, you boot the computer back
up, open the document, and continue editing.
This scenario illustrates that computations interact. In fact, it demon-
strates at least three kinds of interactions between computations. In each
case, one computation provides data to another. First, your email program
retrieves new mail from the server, using the Internet to bridge space. Sec-
ond, your email program provides the attachment to the word processor,
using the operating system’s services to couple the two application pro-
grams. Third, the invocation of the word processor that is running before
your trip provides the partially edited document to the invocation running
after your return, using disk storage to bridge time.
In this book, you will learn about all three kinds of interaction. In all
three cases, interesting software techniques are needed in order to bring the
computations into contact, yet keep them sufficiently at arm’s length that
they don’t compromise each other’s reliability. The exciting challenge, then,
is supporting controlled interaction. This includes support for computations
that share a single computer and interact with one another, as your email
and word processing programs do. It also includes support for data storage
and network communication. This book describes how all these kinds of
support are provided both by operating systems and by additional software
layered on top of operating systems, which is known as middleware.

xi
xii PREFACE

Audience
If you are an upper-level computer science student who wants to under-
stand how contemporary operating systems and middleware products work
and why they work that way, this book is for you. In this book, you will
find many forms of balance. The high-level application programmer’s view,
focused on the services that system software provides, is balanced with a
lower-level perspective, focused on the mechanisms used to provide those
services. Timeless concepts are balanced with concrete examples of how
those concepts are embodied in a range of currently popular systems. Pro-
gramming is balanced with other intellectual activities, such as the scientific
measurement of system performance and the strategic consideration of sys-
tem security in its human and business context. Even the programming
languages used for examples are balanced, with some examples in Java and
others in C or C++. (Only limited portions of these languages are used,
however, so that the examples can serve as learning opportunities, not stum-
bling blocks.)

Systems Used as Examples


Most of the examples throughout the book are drawn from the two dominant
families of operating systems: Microsoft Windows and the UNIX family,
including especially Linux and Mac OS X. Using this range of systems pro-
motes the students’ flexibility. It also allows a more comprehensive array of
concepts to be concretely illustrated, as the systems embody fundamentally
different approaches to some problems, such as the scheduling of processors’
time and the tracking of files’ disk space.
Most of the examples are drawn from the stable core portions of the
operating systems and, as such, are equally applicable to a range of spe-
cific versions. Whenever Microsoft Windows is mentioned without further
specification, the material should apply to Windows NT, Windows 2000,
Windows XP, Windows Server 2003, Windows Vista, Windows 2008, and
Windows 7. All Linux examples are from version 2.6, though much of the
material applies to other versions as well. Wherever actual Linux source
code is shown (or whenever fine details matter for other reasons), the spe-
cific subversion of 2.6 is mentioned in the end-of-chapter notes. Most of the
Mac OS X examples originated with version 10.4, also known as Tiger, but
should be applicable to other versions.
Where the book discusses the protection of each process’s memory, one
PREFACE xiii

additional operating system is brought into the mix of examples, in order


to illustrate a more comprehensive range of alternative designs. The IBM
iSeries, formerly known as the AS/400, embodies an interesting approach
to protection that might see wider application within current students’ life-
times. Rather than giving each process its own address space (as Linux,
Windows, and Mac OS X do), the iSeries allows all processes to share a
single address space and to hold varying access permissions to individual
objects within that space.
Several middleware systems are used for examples as well. The Ora-
cle database system is used to illustrate deadlock detection and recovery
as well as the use of atomic transactions. Messaging systems appear both
as another application of atomic transactions and as an important form of
communication middleware, supporting distributed applications. The spe-
cific messaging examples are drawn from the IBM WebSphere MQ system
(formerly MQSeries) and the Java Message Service (JMS) interface, which is
part of Java 2 Enterprise Edition (J2EE). The other communication middle-
ware examples are Java RMI (Remote Method Invocation) and web services.
Web services are explained in platform-neutral terms using the SOAP and
WSDL standards, as well as through a J2EE interface, JAX-RPC (Java API
for XML-Based RPC).

Organization of the Text


Chapter 1 provides an overview of the text as a whole, explaining what an
operating system is, what middleware is, and what sorts of support these
systems provide for controlled interaction.
The next nine chapters work through the varieties of controlled interac-
tion that are exemplified by the scenario at the beginning of the preface: in-
teraction between concurrent computations on the same system (as between
your email program and your word processor), interaction across time (as
between your word processor before your trip and your word processor after
your trip), and interaction across space (as between your email program and
your service provider’s email server).
The first of these three topics is controlled interaction between computa-
tions operating at one time on a particular computer. Before such interaction
can make sense, you need to understand how it is that a single computer
can be running more than one program, such as an email program in one
window and a word processing program in another. Therefore, Chapter 2
explains the fundamental mechanism for dividing a computer’s attention
xiv PREFACE

between concurrent computations, known as threads. Chapter 3 continues


with the related topic of scheduling. That is, if the computer is dividing its
time between computations, it needs to decide which ones to work on at any
moment.
With concurrent computations explained, Chapter 4 introduces con-
trolled interactions between them by explaining synchronization, which is
control over the threads’ relative timing. For example, this chapter explains
how, when your email program sends a document to your word processor,
the word processor can be constrained to read the document only after the
email program writes it. One particularly important form of synchroniza-
tion, atomic transactions, is the topic of Chapter 5. Atomic transactions
are groups of operations that take place as an indivisible unit; they are
most commonly supported by middleware, though they are also playing an
increasing role in operating systems.
Other than synchronization, the main way that operating systems con-
trol the interaction between computations is by controlling their access to
memory. Chapter 6 explains how this is achieved using the technique known
as virtual memory. That chapter also explains the many other objectives
this same technique can serve. Virtual memory serves as the foundation for
Chapter 7’s topic, which is processes. A process is the fundamental unit of
computation for protected access, just as a thread is the fundamental unit
of computation for concurrency. A process is a group of threads that share a
protection environment; in particular, they share the same access to virtual
memory.
The next three chapters move outside the limitations of a single com-
puter operating in a single session. First, consider the document stored
before a trip and available again after it. Chapter 8 explains persistent
storage mechanisms, focusing particularly on the file storage that operat-
ing systems provide. Second, consider the interaction between your email
program and your service provider’s email server. Chapter 9 provides an
overview of networking, including the services that operating systems make
available to programs such as the email client and server. Chapter 10 ex-
tends this discussion into the more sophisticated forms of support provided
by communication middleware, such as messaging systems, RMI, and web
services.
Finally, Chapter 11 focuses on security. Because security is a pervasive
issue, the preceding ten chapters all provide some information on it as well.
Specifically, the final section of each chapter points out ways in which se-
curity relates to that chapter’s particular topic. However, even with that
coverage distributed throughout the book, a chapter specifically on security
PREFACE xv

is needed, primarily to elevate it out of technical particulars and talk about


general principles and the human and organizational context surrounding
the computer technology.
The best way to use these chapters is in consecutive order. However,
Chapter 5 can be omitted with only minor harm to Chapters 8 and 10, and
Chapter 9 can be omitted if students are already sufficiently familiar with
networking.

Relationship to Computer Science Curriculum 2008


Operating systems are traditionally the subject of a course required for all
computer science majors. In recent years, however, there has been increasing
interest in the idea that upper-level courses should be centered less around
particular artifacts, such as operating systems, and more around cross-
cutting concepts. In particular, the Computing Curricula 2001 (CC2001)
and its interim revision, Computer Science Curriculum 2008 (CS2008), pro-
vide encouragement for this approach, at least as one option. Most colleges
and universities still retain a relatively traditional operating systems course,
however. Therefore, this book steers a middle course, moving in the direc-
tion of the cross-cutting concerns while retaining enough familiarity to be
broadly adoptable.
The following table indicates the placement within this text of knowledge
units from CS2008’s computer science body of knowledge. Those knowledge
units designated as core units within CS2008 are listed in italics. The book
covers all core operating systems (OS) units, as well as one elective OS unit.
The overall amount of coverage for each unit is always at least that rec-
ommended by CS2008, though sometimes the specific subtopics don’t quite
correspond exactly. Outside the OS area, this book’s most substantial cov-
erage is of Net-Centric Computing (NC); another major topic, transaction
processing, comes from Information Management (IM). In each row, the
listed chapters contain the bulk of the knowledge unit’s coverage, though
xvi PREFACE

some topics may be elsewhere.


Knowledge unit
(italic indicates core units in CS2008) Chapter(s)
OS/OverviewOfOperatingSystems 1
OS/OperatingSystemPrinciples 1, 7
OS/Concurrency 2, 4
OS/SchedulingAndDispatch 3
OS/MemoryManagement 6
OS/SecurityAndProtection 7, 11
OS/FileSystems 8
NC/Introduction 9
NC/NetworkCommunication (partial coverage) 9
NC/NetworkSecurity (partial coverage) 9
NC/WebOrganization (partial coverage) 9
NC/NetworkedApplications (partial coverage) 10
IM/TransactionProcessing 5

Your Feedback is Welcome


Comments, suggestions, and bug reports are welcome; please send email to
[email protected]. Bug reports in particular can earn you a bounty of
$2.56 apiece as a token of gratitude. (The great computer scientist Donald
Knuth started this tradition. Given how close to bug-free his publications
have become, it seems to work.) For purposes of this reward, the definition
of a bug is simple: if as a result of your email the author chooses to make a
change, then you have pointed out a bug. The change need not be the one
you suggested, and the bug need not be technical in nature. Unclear writing
qualifies, for example.

Features of the Text


Each chapter concludes with five standard elements. The last numbered sec-
tion within the chapter is always devoted to security matters related to the
chapter’s topic. Next comes three different lists of opportunities for active
participation by the student: exercises, programming projects, and explo-
ration projects. Finally, the chapter ends with historical and bibliographic
notes.
The distinction between exercises, programming projects, and explo-
ration projects needs explanation. An exercise can be completed with no
PREFACE xvii

outside resources beyond paper and pencil: you need just this textbook and
your mind. That does not mean all the exercises are cut and dried, however.
Some may call upon you to think creatively; for these, no one answer is cor-
rect. Programming projects require a nontrivial amount of programming;
that is, they require more than making a small, easily identified change in
an existing program. However, a programming project may involve other
activities beyond programming. Several of them involve scientific measure-
ment of performance effects, for example; these exploratory aspects may
even dominate over the programming aspects. An exploration project, on
the other hand, can be an experiment that can be performed with no real
programming; at most you might change a designated line within an ex-
isting program. The category of exploration projects does not just include
experimental work, however. It also includes projects that require you to do
research on the Internet or using other library resources.

Supplemental Resources
The author of this text is making supplemental resources available on his own
web site. Additionally, the publisher of the earlier first edition commissioned
additional resources from independent supplement authors, which may still
be available through the publisher’s web site and would largely still apply
to this revised edition. The author’s web site, http:// gustavus.edu/ +max/
os-book/ , contains at least the following materials:

• Full text of this revised edition

• Source code in Java, C, or C++ for all programs that are shown in
the text

• Artwork files for all figures in the text

• An errata list that will be updated on an ongoing basis

About the Revised Edition


Course Technology published the first edition of this book in January of 2006
and in October of 2010 assigned the copyright back to the author, giving
him the opportunity to make it freely available. This revised edition closely
follows the first edition; rather than being a thorough update, it is aimed at
three narrow goals:
xviii PREFACE

• All errata reported in the first edition are corrected.

• A variety of other minor improvements appear throughout, such as


clarified explanations and additional exercises, projects, and end-of-
chapter notes.

• Two focused areas received more substantial updates:

– The explanation of Linux’s scheduler was completely replaced


to correspond to the newer “Completely Fair Scheduler” (CFS),
including its group scheduling feature.
– A new section, 4.9, was added on nonblocking synchronization.

In focusing on these limited goals, a key objective was to maintain as


much compatibility with the first edition as possible. Although page num-
bering changed, most other numbers stayed the same. All new exercises
and projects were added to the end of the corresponding lists for that rea-
son. The only newly added section, 4.9, is near the end of its chapter; thus,
the only changed section number is that the old Section 4.9 (“Security and
Synchronization”) became 4.10. Only in Chapter 4 did any figure numbers
change.
It is my hope that others will join me in making further updates and im-
provements to the text. I am releasing it under a Creative Commons license
that allows not just free copying, but also the freedom to make modifications,
so long as the modified version is released under the same terms. In order to
such modifications practical, I’m not just releasing the book in PDF form,
but also as a collection of LaTeX source files that can be edited and then run
through the pdflatex program (along with bibtex and makeindex). The
source file collection also includes PDF files of all artwork figures; Course
Technology has released the rights to the artwork they contracted to have
redrawn.
If you produce a modified version of this text, the Creative Commons
license allows you considerable flexibility in how you make your modified ver-
sion available. I would urge you to send it back to me ([email protected])
so that I can add your version to the main web site–we will all benefit from
having a central repository of progress. Separate materials to supplement
the text would also be welcome. One category that occurs to me is anima-
tions or screencasts; the static figures in the text are rather limited. Another
worthwhile project would be to transform the text into a more contribution-
friendly form, such as a wiki.
PREFACE xix

Acknowledgments
This book was made possible by financial and logistical support from my
employer, Gustavus Adolphus College, and moral support from my family.
I would like to acknowledge the contributions of the publishing team, espe-
cially developmental editor Jill Batistick and Product Manager Alyssa Pratt.
I am also grateful to my students for doing their own fair share of teaching.
I particularly appreciate the often extensive comments I received from the
following individuals, each of whom reviewed one or more chapters: Dan
Cosley, University of Minnesota, Twin Cities; Allen Downey, Franklin W.
Olin College of Engineering; Michael Goldweber, Xavier University; Ramesh
Karne, Towson University; G. Manimaran, Iowa State University; Alexander
Manov, Illinois Institute of Technology; Peter Reiher, University of Califor-
nia, Los Angeles; Rich Salz, DataPower Technology; Dave Schulz, Wisconsin
Lutheran College; Sanjeev Setia, George Mason University; and Jon Weiss-
man, University of Minnesota, Twin Cities. Although I did not adopt all
their suggestions, I did not ignore any of them, and I appreciate them all.
In preparing the revised edition, I took advantage of suggestions from
many readers. I would like to thank all of them, even those I’ve managed
to lose track of, to whom I also apologize. Those I can thank by name are
Joel Adams, Michael Brackney, Jack Briner, Justin Delegard, Ben Follis,
MinChan Kim, Finn Kuusisto, Matt Lindner, Milo Martin, Gabe Schmidt,
Fritz Sieker, and Alex Wauck.
xx PREFACE
Chapter 1

Introduction

1.1 Chapter Overview


This book covers a lot of ground. In it, I will explain to you the basic
principles that underlie a broad range of systems and also give you concrete
examples of how those principles play out in several specific systems. You
will see not only some of the internal workings of low-level infrastructure,
but also how to build higher-level applications on top of that infrastructure
to make use of its services. Moreover, this book will draw on material you
may have encountered in other branches of computer science and engineer-
ing and engage you in activities ranging from mathematical proofs to the
experimental measurement of real-world performance and the consideration
of how systems are used and abused in social context.
Because the book as a whole covers so much ground, this chapter is
designed to give you a quick view of the whole terrain, so that you know
what you are getting into. This is especially important because several of
the topics I cover are interrelated, so that even though I carefully designed
the order of presentation, I am still going to confront you with occasional
forward references. You will find, however, that this introductory chapter
gives you a sufficient overview of all the topics so that you won’t be mystified
when a chapter on one makes some reference to another.
In Section 1.2, I will explain what an operating system is, and in Sec-
tion 1.3, I will do the same for middleware. After these two sections, you
will know what general topic you are studying. Section 1.4 gives you some
reasons for studying that topic, by explaining several roles that I hope this
book will serve for you.
After the very broad overview provided by these initial sections, the

1
2 CHAPTER 1. INTRODUCTION

remaining sections of this chapter are somewhat more focused. Each corre-
sponds to one or more of the later chapters and explains one important cat-
egory of service provided by operating systems and middleware. Section 1.5
explains how a single computer can run several computations concurrently,
a topic addressed in more depth by Chapters 2 and 3. Section 1.6 explains
how interactions between those concurrent computations can be kept under
control, the topic of Chapters 4 through 7. Sections 1.7 and 1.8 extend
the range of interacting computations across time and space, respectively,
through mechanisms such as file systems and networking. They preview
Chapter 8 and Chapters 9 and 10. Finally, Section 1.9 introduces the topic
of security, a topic I revisit at the end of each chapter and then focus on in
Chapter 11.

1.2 What Is an Operating System?


An operating system is software that uses the hardware resources of a com-
puter system to provide support for the execution of other software. Specif-
ically, an operating system provides the following services:

• The operating system allows multiple computations to take place con-


currently on a single computer system. It divides the hardware’s time
between the computations and handles the shifts of focus between the
computations, keeping track of where each one leaves off so that it can
later correctly resume.

• The operating system controls the interactions between the concurrent


computations. It can enforce rules, such as forbidding computations
from modifying data structures while other computations are accessing
those structures. It can also provide isolated areas of memory for
private use by the different computations.

• The operating system can provide support for controlled interaction of


computations even when they do not run concurrently. In particular,
general-purpose operating systems provide file systems, which allow
computations to read data from files written by earlier computations.
This feature is optional because an embedded system, such as the
computer controlling a washing machine, might in some cases run an
operating system, but not provide a file system or other long-term
storage.
1.2. WHAT IS AN OPERATING SYSTEM? 3

• The operating system can provide support for controlled interaction


of computations spread among different computer systems by using
networking. This is another standard feature of general-purpose oper-
ating systems.

These services are illustrated in Figure 1.1.


If you have programmed only general-purpose computers, such as PCs,
workstations, and servers, you have probably never encountered a computer
system that was not running an operating system or that did not allow mul-
tiple computations to be ongoing. For example, when you boot up your own
computer, chances are it runs Linux, Microsoft Windows, or Mac OS X and
that you can run multiple application programs in individual windows on
the display screen. These three operating systems will serve as my primary
examples throughout the book.
To illustrate that a computer can run a single program without an op-
erating system, consider embedded systems. A typical embedded system
might have neither keyboard nor display screen. Instead, it might have
temperature and pressure sensors and an output that controls the fuel in-
jectors of your car. Alternatively, it might have a primitive keyboard and
display, as on a microwave oven, but still be dedicated to running a single
program.
Some of the most sophisticated embedded systems run multiple cooper-
ating programs and use operating systems. However, more mundane embed-
ded systems take a simpler form. A single program is directly executed by
the embedded processor. That program contains instructions to read from
input sensors, carry out appropriate computations, and write to the output
devices. This sort of embedded system illustrates what is possible without
an operating system. It will also serve as a point of reference as I contrast
my definition of an operating system with an alternative definition.
One popular alternative definition of an operating system is that it pro-
vides application programmers with an abstract view of the underlying hard-
ware resources, taking care of the low-level details so that the applications
can be programmed more simply. For example, the programmer can write
a simple statement to output a string without concern for the details of
making each character appear on the display screen.
I would counter by remarking that abstraction can be provided with-
out an operating system, by linking application programs with separately
written libraries of supporting procedures. For example, a program could
output a string using the standard mechanism of a programming language,
such as C++ or Java. The application programmer would not need to know
4 CHAPTER 1. INTRODUCTION

networking
Application Application Application

Application Operating System Operating System

File

(a) (b)

Figure 1.1: Without an operating system, a computer can directly execute


a single program, as shown in part (a). Part (b) shows that with an oper-
ating system, the computer can support concurrent computations, control
the interactions between them (suggested by the dashed line), and allow
communication across time and space by way of files and networking.

anything about hardware. However, rather than running on an operating


system, the program could be linked together with a library that performed
the output by appropriately manipulating a microwave oven’s display panel.
Once running on the oven’s embedded processor, the library and the appli-
cation code would be a single program, nothing more than a sequence of
instructions to directly execute. However, from the application program-
mer’s standpoint, the low-level details would have been successfully hidden.
To summarize this argument, a library of input/output routines is not
the same as an operating system, because it satisfies only the first part of
my definition. It does use underlying hardware to support the execution of
other software. However, it does not provide support for controlled inter-
action between computations. In fairness to the alternative viewpoint, it is
the more historically grounded one. Originally, a piece of software could be
called an operating system without supporting controlled interaction. How-
ever, the language has evolved such that my definition more closely reflects
current usage.
I should also address one other alternative view of operating systems,
because it is likely to be the view you have formed from your own experience
using general-purpose computers. You are likely to think of an operating
system as the software with which you interact in order to carry out tasks
such as running application programs. Depending on the user interface to
which you are accustomed, you might think the operating system is what
allows you to click program icons to run them, or you might think the
operating system is what interprets commands you type.
1.2. WHAT IS AN OPERATING SYSTEM? 5

There is an element of truth to this perception. The operating system


does provide the service of executing a selected application program. How-
ever, the operating system provides this service not to human users clicking
icons or typing commands, but to other programs already running on the
computer, including the one that handles icon clicks or command entries.
The operating system allows one program that is running to start another
program running. This is just one of the many services the operating system
provides to running programs. Another example service is writing output
into a file. The sum total of features the operating system makes available
for application programmers to use in their programs is called the Applica-
tion Programming Interface (API ). One element of the API is the ability to
run other programs.
The reason why you can click a program icon or type in a command
to run a program is that general-purpose operating systems come bundled
with a user-interface program, which uses the operating system API to run
other programs in response to mouse or keyboard input. At a marketing
level, this user-interface program may be treated as a part of the operating
system; it may not be given a prominent name of its own and may not be
available for separate purchase.
For example, Microsoft Windows comes with a user interface known as
Explorer, which provides features such as the Start menu and the ability to
click icons. (This program is distinct from the similarly named web browser,
Internet Explorer.) However, even if you are an experienced Windows user,
you may never have heard of Explorer; Microsoft has chosen to give it a
very low profile, treating it as an integral part of the Microsoft Windows
environment. At a technical level, however, it is distinct from the operating
system proper. In order to make the distinction explicit, the true operating
system is often called the kernel. The kernel is the fundamental portion
of Microsoft Windows that provides an API supporting computations with
controlled interactions.
A similar distinction between the kernel and the user interface applies
to Linux. The Linux kernel provides the basic operating system services
through an API, whereas shells are the programs (such as bash and tcsh)
that interpret typed commands, and desktop environments are the programs,
such as KDE (K Desktop Environment) and GNOME, that handle graphical
interaction.
In this book, I will explain the workings of operating system kernels,
the true operating systems themselves, as opposed to the user-interface pro-
grams. One reason is because user-interface programs are not constructed
in any fundamentally different way than normal application programs. The
6 CHAPTER 1. INTRODUCTION

other reason is because an operating system need not have this sort of user
interface at all. Consider again the case of an embedded system that con-
trols automotive fuel injection. If the system is sufficiently sophisticated,
it may include an operating system. The main control program may run
other, more specialized programs. However, there is no ability for the user
to start an arbitrary program running through a shell or desktop environ-
ment. In this book, I will draw my examples from general-purpose systems
with which you might be familiar, but will emphasize the principles that
could apply in other contexts as well.

1.3 What is Middleware?


Now that you know what an operating system is, I can turn to the other cat-
egory of software covered by this book: middleware. Middleware is software
occupying a middle position between application programs and operating
systems, as I will explain in this section.
Operating systems and middleware have much in common. Both are
software used to support other software, such as the application programs
you run. Both provide a similar range of services centered around con-
trolled interaction. Like an operating system, middleware may enforce rules
designed to keep the computations from interfering with one another. An
example is the rule that only one computation may modify a shared data
structure at a time. Like an operating system, middleware may bring com-
putations at different times into contact through persistent storage and may
support interaction between computations on different computers by pro-
viding network communication services.
Operating systems and middleware are not the same, however. They
rely upon different underlying providers of lower-level services. An operat-
ing system provides the services in its API by making use of the features
supported by the hardware. For example, it might provide API services
of reading and writing named, variable-length files by making use of a disk
drive’s ability to read and write numbered, fixed-length blocks of data. Mid-
dleware, on the other hand, provides the services in its API by making use
of the features supported by an underlying operating system. For example,
the middleware might provide API services for updating relational database
tables by making use of an operating system’s ability to read and write files
that contain the database.
This layering of middleware on top of an operating system, as illustrated
in Figure 1.2, explains the name; middleware is in the middle of the vertical
1.3. WHAT IS MIDDLEWARE? 7

stack, between the application programs and the operating system. Viewed
horizontally rather than vertically, middleware is also in the middle of in-
teractions between different application programs (possibly even running
on different computer systems), because it provides mechanisms to support
controlled interaction through coordination, persistent storage, naming, and
communication.
I already mentioned relational database systems as one example of mid-
dleware. Such systems provide a more sophisticated form of persistent stor-
age than the files supported by most operating systems. I use Oracle as my
primary source of examples regarding relational database systems. Other
middleware I will use for examples in the book includes the Java 2 Plat-
form, Enterprise Edition (J2EE) and IBM’s WebSphere MQ. These systems
provide support for keeping computations largely isolated from undesirable
interactions, while allowing them to communicate with one another even if
running on different computers.
The marketing definition of middleware doesn’t always correspond ex-
actly with my technical definition. In particular, some middleware is of
such fundamental importance that it is distributed as part of the operat-
ing system bundle, rather than as a separate middleware product. As an
example, general-purpose operating systems all come equipped with some
mechanism for translating Internet hostnames, such as www.gustavus.edu,
into numerical addresses. These mechanisms are typically outside the oper-
ating system kernel, but provide a general supporting service to application
programs. Therefore, by my definition, they are middleware, even if not
normally labeled as such.

Application Application Application

Middleware Middleware

Database
Operating System Table Operating System

Figure 1.2: Middleware uses services from an operating system and in turn
provides services to application programs to support controlled interaction.
8 CHAPTER 1. INTRODUCTION

1.4 Objectives for the Book


If you work your way through this book, you will gain both knowledge
and skills. Notice that I did not say anything about reading the book, but
rather about working your way through the book. Each chapter in this book
concludes with exercises, programming projects, exploration projects, and
some bibliographic or historical notes. To achieve the objectives of the book,
you need to work exercises, carry out projects, and occasionally venture
down one of the side trails pointed out by the end-of-chapter notes. Some of
the exploration projects will specifically direct you to do research in outside
sources, such as on the Internet or in a library. Others will call upon you to
do experimental work, such as measuring the performance consequences of
a particular design choice. If you are going to invest that kind of time and
effort, you deserve some idea of what you stand to gain from it. Therefore, I
will explain in the following paragraphs how you will be more knowledgeable
and skilled after finishing the book.
First, you will gain a general knowledge of how contemporary operat-
ing systems and middleware work and some idea why they work that way.
That knowledge may be interesting in its own right, but it also has prac-
tical applications. Recall that these systems provide supporting APIs for
application programmers to use. Therefore, one payoff will be that if you
program applications, you will be positioned to make more effective use of
the supporting APIs. This is true even though you won’t be an expert at
any particular API; instead, you’ll see the big picture of what services those
APIs provide.
Another payoff will be if you are in a role where you need to alter the
configuration of an operating system or middleware product in order to tune
its performance or make it best serve a particular context. Again, this one
book alone won’t give you all the specific knowledge you need about any
particular system, but it will give you the general background to make sense
out of more specialized references.
Perhaps the most significant payoff for learning the details of today’s
systems in the context of the reasons behind their designs is that you will
be in a better position to learn tomorrow’s systems. You will be able to see
in what ways they are different and in what ways they are fundamentally
still the same. You will be able to put new features into context, often as
a new solution to an old problem, or even just as a variant on an existing
solution. If you really get excited by what you learn from this book, you
could even use your knowledge as the foundation for more advanced study
and become one of the people who develops tomorrow’s systems.
1.5. MULTIPLE COMPUTATIONS ON ONE COMPUTER 9

Second, in addition to knowledge about systems, you will learn some


skills that are applicable even outside the context of operating systems and
middleware. Some of the most important skills come from the exploration
projects. For example, if you take those projects seriously, you’ll practice
not only conducting experiments, but also writing reports describing the
experiments and their results. That will serve you well in many contexts.
I have also provided you with some opportunities to develop proficiency
in using the professional literature, such as documentation and the papers
published in conference proceedings. Those sources go into more depth than
this book can, and they will always be more up-to-date.
From the programming projects, you’ll gain some skill at writing pro-
grams that have several interacting components operating concurrently with
one another and that keep their interactions under control. You’ll also de-
velop some skill at writing programs that interact over the Internet. In
neither case will you become a master programmer. However, in both cases,
you will be laying a foundation of skills that are relevant to a range of
development projects and environments.
Another example of a skill you can acquire is the ability to look at the
security ramifications of design decisions. I have a security section in each
chapter, rather than a security chapter only at the end of the book, because I
want you to develop the habit of asking, “What are the security issues here?”
That question is relevant even outside the realm of operating systems and
middleware.
As I hope you can see, studying operating systems and middleware can
provide a wide range of benefits, particularly if you engage yourself in it as
an active participant, rather than as a spectator. With that for motivation,
I will now take you on another tour of the services operating systems and
middleware provide. This tour is more detailed than Sections 1.2 and 1.3,
but not as detailed as Chapters 2 through 11.

1.5 Multiple Computations on One Computer


The single most fundamental service an operating system provides is to allow
multiple computations to be going on at the same time, rather than forcing
each to wait until the previous one has run to completion. This allows
desktop computers to juggle multiple tasks for the busy humans seated in
front of their screens, and it allows server computers to be responsive to
requests originating from many different client computers on the Internet.
Beyond these responsiveness concerns, concurrent computations can also
10 CHAPTER 1. INTRODUCTION

make more efficient use of a computer’s resources. For example, while one
computation is stalled waiting for input to arrive, another computation can
be making productive use of the processor.
A variety of words can be used to refer to the computations underway
on a computer; they may be called threads, processes, tasks, or jobs. In this
book, I will use both the word “thread” and the word “process,” and it is
important that I explain now the difference between them.
A thread is the fundamental unit of concurrency. Any one sequence of
programmed actions is a thread. Executing a program might create multiple
threads, if the program calls for several independent sequences of actions run
concurrently with one another. Even if each execution of a program creates
only a single thread, which is the more normal case, a typical system will be
running several threads: one for each ongoing program execution, as well as
some that are internal parts of the operating system itself.
When you start a program running, you are always creating one or more
threads. However, you are also creating a process. The process is a container
that holds the thread or threads that you started running and protects
them from unwanted interactions with other unrelated threads running on
the same computer. For example, a thread running in one process cannot
accidentally overwrite memory in use by a different process.
Because human users normally start a new process running every time
they want to make a new computation happen, it is tempting to think of
processes as the unit of concurrent execution. This temptation is ampli-
fied by the fact that older operating systems required each process to have
exactly one thread, so that the two kinds of object were in one-to-one corre-
spondence, and it was not important to distinguish them. However, in this
book, I will consistently make the distinction. When I am referring to the
ability to set an independent sequence of programmed actions in motion, I
will write about creating threads. Only when I am referring to the ability
to protect threads will I write about creating processes.
In order to support threads, operating system APIs include features such
as the ability to create a new thread and to kill off an existing thread. In-
side the operating system, there must be some mechanism for switching
the computer’s attention between the various threads. When the operating
system suspends execution of one thread in order to give another thread a
chance to make progress, the operating system must store enough informa-
tion about the first thread to be able to successfully resume its execution
later. Chapter 2 addresses these issues.
Some threads may not be runnable at any particular time, because they
are waiting for some event, such as the arrival of input. However, in general,
1.6. CONTROLLING THE INTERACTIONS BETWEEN COMPUTATIONS11

an operating system will be confronted with multiple runnable threads and


will have to choose which ones to run at each moment. This problem of
scheduling threads’ execution has many solutions, which are surveyed in
Chapter 3. The scheduling problem is interesting, and has generated so
many solutions, because it involves the balancing of system users’ competing
interests and values. No individual scheduling approach will make everyone
happy all the time. My focus is on explaining how the different scheduling
approaches fit different contexts of system usage and achieve differing goals.
In addition I explain how APIs allow programmers to exert control over
scheduling, for example, by indicating that some threads should have higher
priority than others.

1.6 Controlling the Interactions Between Compu-


tations
Running multiple threads at once becomes more interesting if the threads
need to interact, rather than execute completely independently of one an-
other. For example, one thread might be producing data that another thread
consumes. If one thread is writing data into memory and another is read-
ing the data out, you don’t want the reader to get ahead of the writer and
start reading from locations that have yet to be written. This illustrates one
broad family of control for interaction: control over the relative timing of
the threads’ execution. Here, a reading step must take place after the cor-
responding writing step. The general name for control over threads’ timing
is synchronization.
Chapter 4 explains several common synchronization patterns, includ-
ing keeping a consumer from outstripping the corresponding producer. It
also explains the mechanisms that are commonly used to provide synchro-
nization, some of which are supported directly by operating systems, while
others require some modest amount of middleware, such as the Java runtime
environment.
That same chapter also explains a particularly important difficulty that
can arise from the use of synchronization. Synchronization can force one
thread to wait for another. What if the second thread happens to be wait-
ing for the first? This sort of cyclic waiting is known as a deadlock. My
discussion of ways to cope with deadlock also introduces some significant
middleware, because database systems provide an interesting example of
deadlock handling.
In Chapter 5, I expand on the themes of synchronization and middleware
12 CHAPTER 1. INTRODUCTION

by explaining transactions, which are commonly supported by middleware.


A transaction is a unit of computational work for which no intermediate
state from the middle of the computation is ever visible. Concurrent trans-
actions are isolated from seeing each other’s intermediate storage. Addi-
tionally, if a transaction should fail, the storage will be left as it was before
the transaction started. Even if the computer system should catastroph-
ically crash in the middle of a transaction’s execution, the storage after
rebooting will not reflect the partial transaction. This prevents results of a
half-completed transaction from becoming visible. Transactions are incred-
ibly useful in designing reliable information systems and have widespread
commercial deployment. They also provide a good example of how mathe-
matical reasoning can be used to help design practical systems; this will be
the chapter where I most prominently expect you to understand a proof.
Even threads that have no reason to interact may accidentally interact, if
they are running on the same computer and sharing the same memory. For
example, one thread might accidentally write into memory being used by the
other. This is one of several reasons why operating systems provide virtual
memory, the topic of Chapter 6. Virtual memory refers to the technique of
modifying addresses on their way from the processor to the memory, so that
the addresses actually used for storing values in memory may be different
from those appearing in the processor’s load and store instructions. This
is a general mechanism provided through a combination of hardware and
operating system software. I explain several different goals this mechanism
can serve, but the most simple is isolating threads in one process from those
in another by directing their memory accesses to different regions of memory.
Having broached the topic of providing processes with isolated virtual
memory, I devote Chapter 7 to processes. This chapter explains an API
for creating processes. However, I also focus on protection mechanisms, not
only by building on Chapter 6’s introduction of virtual memory, but also by
explaining other forms of protection that are used to protect processes from
one another and to protect the operating system itself from the processes.
Some of these protection mechanisms can be used to protect not just the
storage of values in memory, but also longer-term data storage, such as files,
and even network communication channels. Therefore, Chapter 7 lays some
groundwork for the later treatment of these topics.
Chapter 7 also provides me an opportunity to clarify one point about
threads left open by Chapter 2. By showing how operating systems pro-
vide a protective boundary between themselves and the running application
processes, I can explain where threads fall relative to this boundary. In par-
ticular, there are threads that are contained entirely within the operating
1.7. SUPPORTING INTERACTION ACROSS TIME 13

system kernel, others that are contained entirely within an application pro-
cess, and yet others that cross the boundary, providing support from within
the kernel for concurrent activities within the application process. Although
it might seem natural to discuss these categories of threads in Chapter 2, the
chapter on threads, I really need to wait for Chapter 7 in order to make any
more sense out of the distinctions than I’ve managed in this introductory
paragraph.
When two computations run concurrently on a single computer, the hard
part of supporting controlled interaction is to keep the interaction under con-
trol. For example, in my earlier example of a pair of threads, one produces
some data and the other consumes it. In such a situation, there is no great
mystery to how the data can flow from one to the other, because both are
using the same computer’s memory. The hard part is regulating the use of
that shared memory. This stands in contrast to the interactions across time
and space, which I will address in Sections 1.7 and 1.8. If the producer and
consumer run at different times, or on different computers, the operating
system and middleware will need to take pains to convey the data from one
to the other.

1.7 Supporting Interaction Across Time


General purpose operating systems all support some mechanism for com-
putations to leave results in long-term storage, from which they can be
retrieved by later computations. Because this storage persists even when
the system is shut down and started back up, it is known as persistent stor-
age. Normally, operating systems provide persistent storage in the form of
named files, which are organized into a hierarchy of directories or folders.
Other forms of persistent storage, such as relational database tables and
application-defined persistent objects, are generally supported by middle-
ware. In Chapter 8, I focus on file systems, though I also explain some of
the connections with middleware. For example, I compare the storage of file
directories with that of database indexes. This comparison is particularly
important as these areas are converging. Already the underlying mecha-
nisms are very similar, and file systems are starting to support indexing
services like those provided by database systems.
There are two general categories of file APIs, both of which I cover in
Chapter 8. The files can be made a part of the process’s virtual mem-
ory space, accessible with normal load and store instructions, or they can
be treated separately, as external entities to read and write with explicit
14 CHAPTER 1. INTRODUCTION

operations.
Either kind of file API provides a relatively simple interface to some quite
significant mechanisms hidden within the operating system. Chapter 8 also
provides a survey of some of these mechanisms.
As an example of a simple interface to a sophisticated mechanism, an
application programmer can make a file larger simply by writing additional
data to the end of the file. The operating system, on the other hand, has
to choose the location where the new data will be stored. When disks are
used, this space allocation has a strong influence on performance, because
of the physical realities of how disk drives operate.
Another job for the file system is to keep track of where the data for each
file is located. It also keeps track of other file-specific information, such as
access permissions. Thus, the file system not only stores the files’ data, but
also stores metadata, which is data describing the data.
All these mechanisms are similar to those used by middleware for pur-
poses such as allocating space to hold database tables. Operating systems
and middleware also store information, such as file directories and database
indexes, used to locate data. The data structures used for these naming and
indexing purposes are designed for efficient access, just like those used to
track the allocation of space to stored objects.
To make the job of operating systems and middleware even more chal-
lenging, persistent storage structures are expected to survive system crashes
without significant loss of integrity. For example, it is not acceptable after
a crash for specific storage space to be listed as available for allocation and
also to be listed as allocated to a file. Such a confused state must not occur
even if the crash happened just as the file was being created or deleted.
Thus, Chapter 8 builds on Chapter 5’s explanation of atomic transactions,
while also outlining some other mechanisms that can be used to protect the
integrity of metadata, directories, and indexes.
Persistent storage is crucially important, perhaps even more so in the
Internet age than in prior times, because servers now hold huge amounts of
data for use by clients all over the world. Nonetheless, persistent storage no
longer plays as unique a role as it once did. Once upon a time, there were
many computer systems in which the only way processes communicated was
through persistent storage. Today, that is almost unthinkable, because com-
munication often spans the Internet. Therefore, as I explain in Section 1.8,
operating systems provide support for networking, and middleware provides
further support for the construction of distributed systems.
1.8. SUPPORTING INTERACTION ACROSS SPACE 15

1.8 Supporting Interaction Across Space


In order to build coherent software systems with components operating on
differing computers, programmers need to solve lots of problems. Consider
two examples: data flowing in a stream must be delivered in order, even
if sent by varying routes through interconnected networks, and message
delivery must be incorporated into the all-or-nothing guarantees provided
by transactions. Luckily, application programmers don’t need to solve most
of these problems, because appropriate supporting services are provided by
operating systems and middleware.
I divide my coverage of these services into two chapters. Chapter 9 pro-
vides a foundation regarding networking, so that this book will stand on
its own if you have not previously studied networking. That chapter also
covers services commonly provided by operating systems, or in close conjunc-
tion with operating systems, such as distributed file systems. Chapter 10,
in contrast, explains the higher-level services that middleware provides for
application-to-application communication, in such forms as messaging and
web services. Each chapter introduces example APIs that you can use as an
application programmer, as well as the more general principles behind those
specific APIs.
Networking systems, as I explain in Chapter 9, are generally partitioned
into layers, where each layer makes use of the services provided by the layer
under it in order to provide additional services to the layer above it. At the
bottom of the stack is the physical layer, concerned with such matters as
copper, fiber optics, radio waves, voltages, and wavelengths. Above that is
the link layer, which provides the service of transmitting a chunk of data to
another computer on the same local network. This is the point where the op-
erating system becomes involved. Building on the link-layer foundation, the
operating system provides the services of the network layer and the transport
layer. The network layer arranges for data to be relayed through intercon-
nected networks so as to arrive at a computer that may be elsewhere in the
world. The transport layer builds on top of this basic computer-to-computer
data transmission to provide more useful application-to-application commu-
nication channels. For example, the transport layer typically uses sequence
numbering and retransmission to provide applications the service of in-order,
loss-free delivery of streams of data. This is the level of the most common
operating system API, which provides sockets, that is, endpoints for these
transport-layer connections.
The next layer up is the application layer. A few specialized application-
layer services, such as distributed file systems, are integrated with operating
16 CHAPTER 1. INTRODUCTION

systems. However, most application-layer software, such as web browsers


and email programs, is written by application programmers. These applica-
tions can be built directly on an operating system’s socket API and exchange
streams of bytes that comply with standardized protocols. In Chapter 9, I
illustrate this possibility by showing how web browsers and web servers
communicate.
Alternatively, programmers of distributed applications can make use of
middleware to work at a higher level than sending bytes over sockets. I
show two basic approaches to this in Chapter 10: messaging and Remote
Procedure Calls (RPCs). Web services are a particular approach to stan-
dardizing these kinds of higher-level application communication, and have
been primarily used with RPCs: I show how to use them in this way.
In a messaging system, an application program requests the delivery of a
message. The messaging system not only delivers the message, which lower-
level networking could accomplish, but also provides additional services. For
example, the messaging is often integrated with transaction processing. A
successful transaction may retrieve a message from an incoming message
queue, update a database in response to that message, and send a response
message to an outgoing queue. If the transaction fails, none of these three
changes will happen; the request message will remain in the incoming queue,
the database will remain unchanged, and the response message will not be
queued for further delivery. Another common service provided by messag-
ing systems is to deliver a message to any number of recipients who have
subscribed to receive messages of a particular kind; the sender need not be
aware of who the actual receivers are.
Middleware can also provide a mechanism for Remote Procedure Call
(RPC ), in which communication between a client and a server is made to
look like an ordinary programming language procedure call, such as invoking
a method on an object. The only difference is that the object in question is
located on a different computer, and so the call and return involve network
communication. The middleware hides this complexity, so that the applica-
tion programmer can work largely as though all the objects were local. In
Chapter 10, I explain this concept more fully, and then go on to show how it
plays out in the form of web services. A web service is a an application-layer
entity that programs can communicate with using standardized protocols
similar to those humans use to browse the web.
1.9. SECURITY 17

1.9 Security
Operating systems and middleware are often the targets of attacks by ad-
versaries trying to defeat system security. Even attacks aimed at application
programs often relate to operating systems and middleware. In particular,
easily misused features of operating systems and middleware can be the
root cause of an application-level vulnerability. On the other hand, operat-
ing systems and middleware provide many features that can be very helpful
in constructing secure systems.
A system is secure if it provides an acceptably low risk that an adversary
will prevent the system from achieving its owner’s objectives. In Chapter 11,
I explain in more detail how to think about risk and about the conflicting
objectives of system owners and adversaries. In particular, I explain that
some of the most common objectives for owners fall into four categories:
confidentiality, integrity, availability, and accountability. A system provides
confidentiality if it prevents inappropriate disclosure of information, integrity
if it prevents inappropriate modification or destruction of information, and
availability if it prevents inappropriate interference with legitimate usage. A
system provides accountability if it provides ways to check how authorized
users have exercised their authority. All of these rely on authentication, the
ability of a system to verify the identity of a user.
Many people have a narrow view of system security. They think of those
features that would not even exist, were it not for security issues. Clearly,
logging in with a password (or some other, better form of authentication) is
a component of system security. Equally clearly, having permission to read
some files, but not others, is a component of system security, as are crypto-
graphic protocols used to protect network communication from interception.
However, this view of security is dangerously incomplete.
You need to keep in mind that the design of any component of the
operating system can have security consequences. Even those parts whose
design is dominated by other considerations must also reflect some proactive
consideration of security consequences, or the overall system will be insecure.
In fact, this is an important principle that extends beyond the operating
system to include application software and the humans who operate it.
Therefore, I will make a habit of addressing security issues in every
chapter, rather than only at the end of the book. Specifically, each chapter
concludes with a section pointing out some of the key security issues asso-
ciated with that chapter’s topic. I also provide a more coherent treatment
of security by concluding the book as a whole with Chapter 11, which is
devoted exclusively to security. That chapter takes a holistic approach to
18 CHAPTER 1. INTRODUCTION

security, in which human factors play as important a role as technical ones.

Exercises
1.1 What is the difference between an operating system and middleware?

1.2 What do operating systems and middleware have in common?

1.3 What is the relationship between threads and processes?

1.4 What is one way an operating system might isolate threads from un-
wanted interactions, and what is one way that middleware might do
so?

1.5 What is one way an operating system might provide persistent storage,
and what is one way middleware might do so?

1.6 What is one way an operating system might support network commu-
nication, and what is one way middleware might do so?

1.7 Of all the topics previewed in this chapter, which one are you most
looking forward to learning more about? Why?

Programming Project
1.1 Write, test, and debug a program in the language of your choice to
carry out any task you choose. Then write a list of all the services
you suspect the operating system is providing in order to support the
execution of your sample program. If you think the program is also
relying on any middleware services, list those as well.

Exploration Projects
1.1 Look through the titles of the papers presented at several recent con-
ferences hosted by the USENIX Association (The Advanced Comput-
ing Systems Association); you can find the conference proceedings at
www.usenix.org. To get a better idea what an individual paper is
about, click the title to show the abstract, which is a short summary
of the paper. Based on titles and abstracts, pick out a few papers that
you think would make interesting supplementary reading as you work
1.9. SECURITY 19

your way through this book. Write down a list showing the biblio-
graphic information for the papers you selected and, as near as you
can estimate, where in this book’s table of contents they would be
appropriate to read.

1.2 Conduct a simple experiment in which you take some action on a


computer system and observe what the response is. You can choose
any action you wish and any computer system for which you have
appropriate access. You can either observe a quantitative result, such
as how long the response takes or how much output is produced, or
a qualitative result, such as in what form the response arrives. Now,
try replicating the experiment. Do you always get the same result?
Similar ones? Are there any factors that need to be controlled in
order to get results that are at least approximately repeatable? For
example, to get consistent times, do you need to reboot the system
between each trial and prevent other people from using the system?
To get consistent output, do you need to make sure input files are
kept unchanged? If your action involves a physical device, such as a
printer, do you have to control variables such as whether the printer
is stocked with paper? Finally, write up a careful report, in which
you explain both what experiment you tried and what results you
observed. You should explain how repeatable the results proved to be
and what limits there were on the repeatability. You should describe
the hardware and software configuration in enough detail that someone
else could replicate your experiment and would be likely to get similar
results.

Notes
The idea that an operating system should isolate computations from un-
wanted interactions, and yet support desirable interactions, has a long her-
itage. A 1962 paper [38] by Corbató, Daggett, and Daley points out that
“different user programs if simultaneously in core memory may interfere with
each other or the supervisor program so some form of memory protection
mode should be available when operating user programs.” However, that
same paper goes on to say that although “great care went into making each
user independent of the other users . . . it would be a useful extension of the
system if this were not always the case,” so that the computer system could
support group work, such as war games.
20 CHAPTER 1. INTRODUCTION

Middleware is not as well-known to the general public as operating sys-


tems are, though commercial information-system developers would be lost
without it. One attempt to introduce middleware to a somewhat broader
audience was Bernstein’s 1996 survey article [17].
The USENIX Association, mentioned in Exploration Project 1.1, is only
one of several very fine professional societies holding conferences related to
the subject matter of this book. The reason why I specifically recommended
looking through their proceedings is that they tend to be particularly ac-
cessible to students. In part this is because USENIX focuses on bringing
practitioners and academics together; thus, the papers generally are prag-
matic without being superficial. The full text is available on their web site.
Chapter 2

Threads

2.1 Introduction
Computer programs consist of instructions, and computers carry out se-
quences of computational steps specified by those instructions. We call
each sequence of computational steps that are strung together one after an-
other a thread. The simplest programs to write are single-threaded, with
instructions that should be executed one after another in a single sequence.
However, in Section 2.2, you will learn how to write programs that produce
more than one thread of execution, each an independent sequence of compu-
tational steps, with few if any ordering constraints between the steps in one
thread and those in another. Multiple threads can also come into existence
by running multiple programs, or by running the same program more than
once.
Note the distinction between a program and a thread; the program con-
tains instructions, whereas the thread consists of the execution of those
instructions. Even for single-threaded programs, this distinction matters.
If a program contains a loop, then a very short program could give rise
to a very long thread of execution. Also, running the same program ten
times will give rise to ten threads, all executing one program. Figure 2.1
summarizes how threads arise from programs.
Each thread has a lifetime, extending from the time its first instruc-
tion execution occurs until the time of its last instruction execution. If two
threads have overlapping lifetimes, as illustrated in Figure 2.2, we say they
are concurrent. One of the most fundamental goals of an operating sys-
tem is to allow multiple threads to run concurrently on the same computer.
That is, rather than waiting until the first thread has completed before a

21
22 CHAPTER 2. THREADS

Single-threaded program Multiple single-threaded programs

Thread Thread A

Thread B

Multi-threaded program Multiple runs of one single-threaded program

Spawn
Thread A Thread A

Thread B
Thread B

Figure 2.1: Programs give rise to threads

Sequential threads

Concurrent threads running simultaneously on two processors

Concurrent threads (with gaps in their executions) interleaved on one processor

Figure 2.2: Sequential and concurrent threads


2.2. EXAMPLE OF MULTITHREADED PROGRAMS 23

second thread can run, it should be possible to divide the computer’s atten-
tion between them. If the computer hardware includes multiple processors,
then it will naturally be possible to run threads concurrently, one per pro-
cessor. However, the operating system’s users will often want to run more
concurrent threads than the hardware has processors, for reasons described
in Section 2.3. Therefore, the operating system will need to divide each pro-
cessor’s attention between multiple threads. In this introductory textbook
I will mostly limit myself to the case of all the threads needing to be run on
a single processor. I will explicitly indicate those places where I do address
the more general multi-processor case.
In order to make the concept of concurrent threads concrete, Section 2.2
shows how to write a program that spawns multiple threads each time the
program is run. Once you know how to create threads, I will explain in Sec-
tion 2.3 some of the reasons why it is desirable to run multiple threads con-
currently and will offer some typical examples of the uses to which threads
are put.
These first two sections explain the application programmer’s view of
threads: how and why the programmer would use concurrent threads. This
sets us up for the next question: how does the operating system support
the application programmer’s desire for concurrently executing threads? In
Sections 2.4 and 2.5, we will examine how the system does so. In this chap-
ter, we will consider only the fundamentals of how the processor’s attention
is switched from one thread to another. Some of the related issues I address
in other chapters include deciding which thread to run at each point (Chap-
ter 3) and controlling interaction among the threads (Chapters 4, 5, 6, and
7). Also, as explained in Chapter 1, I will wait until Chapter 7 to explain the
protection boundary surrounding the operating system. Thus, I will need
to wait until that chapter to distinguish threads that reside entirely within
that boundary, threads provided from inside the boundary for use outside of
it, and threads residing entirely outside the boundary (known as user-level
threads or, in Microsoft Windows, fibers).
Finally, the chapter concludes with the standard features of this book:
a brief discussion of security issues, followed by exercises, programming and
exploration projects, and notes.

2.2 Example of Multithreaded Programs


Whenever a program initially starts running, the computer carries out the
program’s instructions in a single thread. Therefore, if the program is in-
24 CHAPTER 2. THREADS

tended to run in multiple threads, the original thread needs at some point
to spawn off a child thread that does some actions, while the parent thread
continues to do others. (For more than two threads, the program can repeat
the thread-creation step.) Most programming languages have an application
programming interface (or API) for threads that includes a way to create
a child thread. In this section, I will use the Java API and the API for
C that is called pthreads, for POSIX threads. (As you will see throughout
the book, POSIX is a comprehensive specification for UNIX-like systems,
including many APIs beyond just thread creation.)
Realistic multithreaded programming requires the control of thread in-
teractions, using techniques I show in Chapter 4. Therefore, my examples in
this chapter are quite simple, just enough to show the spawning of threads.
To demonstrate the independence of the two threads, I will have both
the parent and the child thread respond to a timer. One will sleep three
seconds and then print out a message. The other will sleep five seconds and
then print out a message. Because the threads execute concurrently, the
second message will appear approximately two seconds after the first. (In
Programming Projects 2.1, 2.2, and 2.3, you can write a somewhat more
realistic program, where one thread responds to user input and the other to
the timer.)
Figure 2.3 shows the Java version of this program. The main program
first creates a Thread object called childThread. The Runnable object asso-
ciated with the child thread has a run method that sleeps three seconds (ex-
pressed as 3000 milliseconds) and then prints a message. This run method
starts running when the main procedure invokes childThread.start(). Be-
cause the run method is in a separate thread, the main thread can continue
on to the subsequent steps, sleeping five seconds (5000 milliseconds) and
printing its own message.
Figure 2.4 is the equivalent program in C, using the pthreads API. The
child procedure sleeps three seconds and prints a message. The main proce-
dure creates a child_thread running the child procedure, and then itself
sleeps five seconds and prints a message. The most significant difference
from the Java API is that pthread_create both creates the child thread
and starts it running, whereas in Java those are two separate steps.
In addition to portable APIs, such as the Java and pthreads APIs, many
systems provide their own non-portable APIs. For example, Microsoft Win-
dows has the Win32 API, with procedures such as CreateThread and Sleep.
In Programming Project 2.4, you can modify the program from Figure 2.4
to use this API.
2.2. EXAMPLE OF MULTITHREADED PROGRAMS 25

public class Simple2Threads {


public static void main(String args[]){
Thread childThread = new Thread(new Runnable(){
public void run(){
sleep(3000);
System.out.println("Child is done sleeping 3 seconds.");
}
});
childThread.start();
sleep(5000);
System.out.println("Parent is done sleeping 5 seconds.");
}

private static void sleep(int milliseconds){


try{
Thread.sleep(milliseconds);
} catch(InterruptedException e){
// ignore this exception; it won’t happen anyhow
}
}
}

Figure 2.3: A simple multithreaded program in Java


Another Random Scribd Document
with Unrelated Content
station indeed. Excepting a Buddha, none is equal to him, either in
knowledge or miraculous powers, both of which he possesses to a
preëminent extent. The Arhat after his death enters at once into
Nirvâna. The Anâgâmin enters the third path (from the bottom), and
is exempt from re-birth except in the world of Devas, or gods. He
who obtains or "sees" the fruit of the second path is born once more
in the world of gods or in that of men. Finally, the Srotâpanna
undergoes re-birth either among gods or men seven times, and is
then delivered from the stream of existence.[68]
Below the fortunate travelers along the path stands the mass of
ordinary believers. All of these, of course, aim ultimately—or should
aim—at that perfection of knowledge and of character which ensures
Nirvâna; but in popular Buddhism at the present day this distant
goal appears to be well-nigh forgotten, and to have given place to
some heaven, or place of enjoyment, above which the general hope
does not rise.
Believers in general are divided into two classes, Bhikshus and
Bhikshunîs, or monks and nuns; and Upâsakas, lay disciples. The
distinction between these classes is well illustrated by the following
extract from a sacred book, the consideration of which will lead us
from the domain of theology into that of morality:—"What is to be
done in the condition of a mendicant?—The rules of chastity must be
observed during the whole of life.—That is not possible; are there no
other means?—There are others, friend; namely, to be a devotee
(Upâsaka).—What is to be done in this condition?—It is necessary
during the whole of one's life to abstain from murder, theft,
pleasure, lying, and the use of intoxicating liquors." The injunctions
thus stated to be binding on the laity are in fact the first five of the
ten commandments, pleasure being simply a designation of
unchastity, which the layman as well as the monk is here ordered to
eschew. The first five commandments are in fact general, referring
to universal ethical obligations, not merely to monastic discipline, like
the other five. But Buddhist morality is by no means merely
negative. It enjoins not only abstinence from such definite sins as
these, but the practice of positive virtues in their most exalted
forms. In no system is benevolence, or, as it is termed in the English
New Testament, charity, more emphatically inculcated. Exhibited, as
we have seen it is, in the highest degree by Buddha himself, it
should be illustrated to the extent of their capabilities by all his
followers. Chastity is the subject of almost equal praise. And the
other virtues come in for their share of recognition, the general
object of the examples held up to admiration being to exhort the
faithful to a life spotless in all its parts, like that of their master. With
this aim the legends related generally fall into some such form as
this: Characters appear who undergo some suffering, but receive
also some great reward, such as meeting with Buddha, and
embracing his religion. It is then explained by Buddha that the
sufferings were the result of some bad action done in a former life,
and the benefit received the result of some good action; while he
will probably add that he himself in that bygone age stood in the
relation of a benefactor to the recipient of his faith. Or a number of
persons are introduced playing various parts, good and evil, and
receiving blessings or misfortunes. One of these is conspicuous by
the excellence of his conduct. Then, at the end of the story, the
disciples are told not to imagine that this model of virtue is any other
than Sakyamuni himself, while the other characters are translated,
according to their special peculiarities, each into some individual
living at the time, and forming either one of Buddha's retinue, or
connected with him by ties of kindred, or (if wicked) marked by
hostility to his person or doctrine. Thus, the bad parts in these
dramas are often allotted to his cousin Devadatta, who figures in
these Scriptures as his typical opponent.
The essential doctrine of all these moral fictions—the corner-stone
of Buddhist ethics—is that every single act of virtue receives its
reward, every single transgression its punishment. The
consequences of our good deeds or misdeeds, mystically embodied
in our Karma, follow us from life to life, from earth to heaven, from
earth to hell, and from heaven or hell to earth again. Karma
expresses an idea by no means easily seized. Perhaps it may be
defined as the sum total of our moral actions, good and bad,
conceived as a kind of entity endowed with the force of destiny. It is
our Karma that determines the character of our successive
existences. It is our Karma that determines whether our next birth
shall be in heaven or hell, in a happy or miserable condition here
below. And as Karma is but the result of our own actions, each of
which must bear its proper fruit, the balance, either on the credit or
debit side of our account, must always be paid; to us or by us, as
the case may be.
Let us illustrate this by an instance or two. A certain prince,
named Kunâla, remarkable for his personal beauty, had been
deprived of his eyes through an intrigue in his father's harem.
Sakyamuni, in pointing the moral, informs his disciples that Kunâla
had formerly been a huntsman, who finding five hundred gazelles in
a cave, had put out their eyes in order to preclude their escape. For
this cruelty he had suffered the pains of hell for hundreds of
thousands of years, and had then had his eyes put out in human
existences. But Kunâla also enjoyed great advantages. He was the
son of a king, he possessed an attractive person, and, above all, he
had embraced the truths of Buddhism. Why was this? Because he
had once caused a Stûpa of a former Buddha, which an unbelieving
monarch had suffered to be pulled to pieces, to be rebuilt, and had
likewise restored a statue of this same Buddha which had been spoilt
(H. B. I., p. 414). The truly Buddhistic spirit of this young prince is
evinced by the circumstance that he interceded earnestly with his
father for the pardon of his stepmother who had caused him to be
so cruelly mutilated.
In another case, a poor old woman, who had led a miserable
existence as the slave of an unfeeling master and mistress, was re-
born in one of the heavens, known as that of the three-and-thirty
gods. Five hundred goddesses descended to the cemetery where
she had been heedlessly thrown into the ground, strewed flowers on
her bones, and offered them spices. The reason of all this honor
was, that on the previous day she had met with Kâtyâyana, an
apostle of Buddhism, had drawn water and presented it to him in his
bowl, and had consequently received a blessing from him, with an
exhortation to enter her mistress's room after she had gone to sleep,
and sitting on a heap of hay to fix her mind exclusively upon
Buddha. This advice she had attended to, and had consequently
received the above-named reward (W. u. T., p. 153).
Good and evil, under this elaborate system, are thus the seeds
which, by an invariable law, produce their appropriate fruits in a
future state. The doctrine may in fact be best described in the words
attributed to its author:—"A previous action does not die; be it good
or evil, it does not die; the society of the virtuous is not lost; that
which is done, that which is said, for the Aryas,[69] for these grateful
persons, never dies. A good action well done, a bad action wickedly
done, when they have arrived at their maturity, equally bear an
inevitable fruit" (H. B. I., p. 98).

Section V.—The Zend-Avesta.[70]

Persia was once a great power in the world; the Persian religion, a
conquering and encroaching faith. The Persian Empire threatened to
destroy the independence of Greece. It held the Jews in actual
subjection, and its religious views profoundly influenced the
development of theirs. Through the Jews, its ideas have penetrated
the Christian world, and leavened Europe. It once possessed an
extensive and remarkable sacred literature, but a few scattered
fragments of which have descended to us. These fragments,
recovered and first translated by Anquetil du Perron, have been but
imperfectly elucidated as yet by European scholars; and there can be
no doubt that much more light remains to be cast upon them by
philology as it progresses. Such as they are, however, I shall make
use of the translations already before us to give my readers an
imperfect account of the character of the Parsee Scriptures.
These compositions are the productions of several centuries and
are widely separated from one another in the character of their
thought, and in the objects of worship proposed to the faithful
follower of Zarathustra. The oldest among them, which may belong
to the time of the prophet himself, are considered by Haug to be as
ancient as b.c. 1200, while the youngest were very likely as recent as
b.c. 500.

Haug considers the Avesta to be the most ancient text, while the
Zend was a kind of commentary upon this already sacred book.
Taking the several portions of the Zend-Avesta in their
chronological order (as far as this can be ascertained), we shall
begin with the five Gâthâs, which are pronounced by their translator
to be "by far the oldest, weightiest, and most important pieces of
the Zend-Avesta" (F. G., xiii). Some portions of these venerable
hymns are even attributed by him to Zarathustra himself; but this—
except where the prophet is in some way named as the author—
must be considered only as an individual opinion, which can carry no
positive conviction to other minds until it is supported by stronger
evidence than any at present accessible. Meantime, we may rest
assured that we possess among these hymns some undoubted
productions of the Zarathustrian age.

Subdivision 1.—The Five Gâthâs.

Proceeding to the individual Gâthâs, we find that the first, which


begins with the 28th chapter of the Yaçna, bears the following
heading: "The revealed Thought, the revealed Word, the revealed
Deed of the truthful Zarathustra.—The immortal saints chanted the
hymns."[71]
The Gâthâ Ahunavaiti—such is its title—then proceeds:—
1. "Adoration to you, ye truthful hymns!
2. "I raise aloft my hands in devotion, and worship first
all true works of the wise and holy Spirit, and the
Understanding of the pious Disposition, in order to
participate in this happiness.
3. "I will draw near to you with a pious disposition, O
Wise One! O Living One! with the request that you will
grant me the mundane and the spiritual life. By truth are
these possessions to be obtained, which he who is self-
illuminated bestows on those who strive for them" (F. G.,
vol. i. p. 24.—Yaçna, xxviii. 1-3).
The most important portion of this Gâthâ is the 30th chapter,
because in it we have a vivid picture of the conflict in which the
religion of Ahura-Mazda was born. Philological inquiry has rendered
it clear beyond dispute, that Parseeism took its rise in a religious
schism between two sections of the great Aryan race, at a period so
remote that the occupation of Hindoostan by an offshoot of that race
had not yet occurred. The common ancestors of Hindus and Persians
still dwelt together in Central Asia, when the great Parsee
Reformation disturbed their harmony; the one section adopting, or
adhering to, the Vedic polytheism which they subsequently carried to
India; the other embracing the more monotheistic creed which
afterwards became the national religion of Persia.
The following hymn of the reformers carries us into the very midst
of the strife:—
1. "I will now tell you who are assembled here, the wise
sayings of the most wise, the praises of the living God,
and the songs of the good spirit, the sublime truth which I
see arising out of these sacred flames.
2. "You shall, therefore, hearken to the soul of nature
(i. e., plough and cultivate the earth);[72] contemplate the
beams of fire with a most pious mind! Every one, both
men and women, ought to-day to choose his creed
(between the Deva and the Ahura religion). Ye offspring of
renowned ancestors, awake to agree with us (i. e., to
approve of my lore, to be delivered to you at this
moment)!"
(The prophet begins to deliver the words, revealed to him through
the sacred flames.)
3. "In the beginning there was a pair of twins, two
spirits, each of a peculiar activity; these are the good and
the base, in thought, word, and deed. Choose one of
these two spirits! Be good, not base!
4. "And these two spirits united created the first
(material things); the one, the reality, the other, the non-
reality. To the liars (the worshipers of the devas, i. e.,
gods) existence will become bad, whilst the believer in the
true god enjoys prosperity.
5. "Of these two spirits you must choose one, either the
evil, the originator of the worst actions, or the true holy
spirit. Some may wish to have the hardest lot (i. e., those
who will not leave the polytheistic deva-religion), others
adore Ahura-Mazda by means of sincere actions.
6. "You cannot belong to both of them (i. e., you cannot
be worshipers of the one true God and of many gods at
the same time). One of the devas, against whom we are
fighting, might overtake you, when in deliberation (what
faith you are to embrace), whispering you to choose the
no-mind. Then the devas flock together to assault the two
lives (the life of the body, and that of the soul), praised by
the prophets" (Parsees, pp. 141, 142.—Yasna, 30).
In another portion of this Gâthâ it is interesting to observe the
spirit of religious zeal breaking out, as it so generally does, into the
language of persecution:—
xxxi. 18. "Do not listen to the sayings and precepts of
the wicked (the evil spirit), because he has given to
destruction house, village, district, and province.
Therefore kill them (the wicked) with the sword!"
The wicked, as appears from the context, are those who did not
accept the Zarathustrian revelation.
In the second Gâthâ, or Gâthâ Ustavaiti, there are some very
curious passages. A few have been quoted in the notice of
Zarathustra. The following verses indicate the nature of the worship
addressed to Ahura-Mazda in the most ancient period of the Parsee
religion:—
xliii. 2. "I believe thee to be the best thing of all, the
source of light for the world. Everybody shall choose thee
(believe in thee) as the source of light, thee, thee, holiest
spirit Mazda! Thou createst all good true things by means
of the power of thy good mind at any time, and promisest
us (who believe in thee) a long life.
4. "I will believe thee to be the powerful, holy (god)
Mazda! For thou givest with thy hand, filled with helps,
good to the pious man, as well as to the impious, by
means of the warmth of the fire strengthening the good
things. For this reason the vigor of the good mind has
fallen to my lot.
5. "Thus I believe in thee as the holy God, thou living
Wise One! Because I beheld thee to be the primeval cause
of life in the creation. For thou hast made (instituted) holy
customs and words, thou hast given a bad fortune
(emptiness) to the base, and a good one to the good
man. I will believe in thee, thou glorious God! in the last
(future) period of creation" (Parsees, p. 149).
xliv. 3. "That which I shall ask thee, tell it me right, thou
living God! Who was in the beginning the father and
creator of truth? Who made the way for the sun and
stars? Who causes the moon to increase and wane, if not
thou? This I wish to know besides what I already know.
4. "That I will ask thee, tell it me right, thou living God!
Who is holding the earth and the skies above it? Who
made the waters and the trees of the field? Who is in the
winds and storms that they so quickly run? Who is the
creator of the good-minded beings, thou Wise One?
5. "That I will ask thee, tell it me right, thou living God!
Who made the lights of good effect and the darkness?
Who made the sleep of good effect and the activity? Who
made morning, noon and night, always reminding the
priest of his duties?" (Ibid., p. 150.)
xlvi. 7. "Who is appointed protector of my property,
Wise One! when the wicked endeavor to hurt me? Who
else, if not thy fire, and thy mind, through which thou hast
created the existence (good beings), thou living God! Tell
me the power necessary for holding up the religion" (Ibid.,
p. 156).
The third Gâthâ is termed Çpeñta-Mainyus. It begins with praise of
Ahura-Mazda as the giver of the two forces of perfection and
immortality. From this holiest spirit proceeds all the good contained
in the words uttered by the good mind. He is the father of all truth.
Of such a spirit is he who created this earth with the fire resting in
its lap. Ahura-Mazda placed the gift of fire in the sticks that are
rubbed together by the duality of truth and piety. The following
verse refers to Mazda's prophet, Zarathustra:—
xlviii. 4. "He who created, by means of his wisdom, the
good and the no-mind in thinking, words, and deeds,
rewards his obedient followers with prosperity. Art thou
(Mazda) not he in whom the last cause of both intellects
(good and evil) is hidden?" (Parsees, p. 159).
The concluding chapter of this Gâthâ is a hymn of praise supposed
to emanate from the Spirit of Earth and to be addressed to the
highest genii. It is not without beauty and sublimity, but I forbear to
make quotations from it, as some of its most interesting verses are
noticed elsewhere.
The fourth and fifth Gâthâ are much shorter, and are considered
by Haug as an appendix. The following verse may serve as a
specimen of the former:—
lii. 20. "May you all together grant us this your help,
truth through the good mind, and the good word in which
piety consists. Be lauded and praised. The Wise One
bestows happiness.
21. "Has not the Holy One, the living wise one, created
the radiant truth, and possession with the good mind by
means of the wise sayings of Ârmaiti, by her actions and
her faith?
22. "The living Wise One knows what is always the best
for me in the adoration of those who existed and still
exist. These I will invoke with mention of their names, and
I will approach them as their panegyrist" (F. G., vol. ii. p.
56).
Of the first three verses of the fifth Gâthâ I have spoken above (p.
184). The fourth and fifth run thus:—
liii. 4. "I will zealously confess this your faith, which the
blessed one destined to the landlord for the country
people, to the truthful householder for the truthful people,
ever extending the glory and the beauty of the good mind,
which the living Wise One has bestowed on the good faith
for ever and ever.
5. "I proclaim formulæ of blessing to girls about to be
married: Attend! attend to them! You possess by means of
those formulæ the life of the good mind. Let one receive
the other with upright heart; for thus only will you
prosper" (F. G., vol. ii. p. 57).

Subdivision 2.—Yaçna 35-41, or the Yaçna of seven chapters.


The Yaçna of seven chapters, which in the present arrangement of
the text is inserted between the first and second Gâthâs, is of more
recent date than the Gâthâs, but more ancient than the rest of the
Zend-Avesta. "It appears to be the work of one of the earliest
successors of the prophet, called in ancient times Zarathustra or
Zarathustrotema, who, deviating somewhat from the high and pure
monotheistic principles of Çpitama, made some concessions to the
adherents of the ante-Zoroastrian religion by addressing prayers to
other beings than Ahura-Mazda" (Parsee, p. 219). The seven
chapters may be most accurately described as Psalms of praise, in
which a great variety of objects, spiritual and natural, receive a
tribute of pious reverence from the worshiper. They are not,
however, on that account to be considered as gods, or as in any way
the equals of Ahura-Mazda, who is still supreme. The beings thus
addressed are portions of the "good creation," or of the things
created by the good power, Ahura-Mazda; and they are either
subjects of his spiritual kingdom, such as the Amesha-çpentas
(seven very important spirits), or they are simply portions of the
material universe treated as semi-divine, and exalted to objects of
religious worship. Thus in the last chapter of this section, the author
directs his laudations to the following, among other, genii and
powers: the dwelling of the waters, the parting of the Ways,
mountains, the wind, the earth, the pure ass in Lake Vouru-Kasha,
this lake itself, the Soma, the flowing of the waters, the flying of the
birds. It is plain from this enumeration that we are already a step
beyond the simple adoration of Ahura-Mazda so conspicuous in the
Gâthâs, and that the door is opened to the multitude of spirits and
divinities that make their appearance in other parts of the Parsee
ritual.
This section of the Yaçna opens, however, with a striking address
to Ahura-Mazda:[73]—
xxxv. 1. "We worship Ahura-Mazda the pure, the master
of purity. We worship the Amesha-çpentas (the
archangels), the possessors of good, the givers of good.
We worship the whole creation of the true spirit, both the
spiritual and terrestrial, all that supports (raises) the
welfare of the good creation, and the spread of the good
Mazdayaçna religion.
2. "We praise all good thoughts, all good words, all
good deeds, which are and will be (which are being done
and which have been done) and we likewise keep clean
and pure all that is good.
3. "O Ahura-Mazda, thou true happy being! we strive to
think, to speak, and to do only those of all actions which
might be best fitted to promote the two lives (that of the
body and of the soul).
4. "We beseech the spirit of earth by means of these
best works (agriculture) to grant us beautiful and fertile
fields, to the believer as well as to the unbeliever, to him
who has riches as well as to him who has no possession"
(Parsees, p. 163).
The following invocation of fire deserves to be mentioned before
we quit this portion of the Yaçna:—
xxxvi. 4. "Happy is the man to whom thou comest in
power, O Fire, Son of Ahura-Mazda.
5. "Friendlier than the friendliest, more deserving of
adoration than the most adorable.
6. "Mayest thou come to us helpfully to the greatest of
transactions....
9. "O Fire, Son of Ahura-Mazda, we approach thee
10. "with a good spirit, with good purity" (Av., ii. 137).

Subdivision 3.—Yaçna, Chapter XII.


This chapter is stated by Haug to be written in the Gâthâ dialect;
it is therefore extremely ancient, and as it contains the Confession of
Faith made by Zarathustrian converts on their abandonment of
idolatry, or worship of the Devas, it is of sufficient importance to be
quoted at length:—
xii. 1. "I cease to be a Deva worshiper. I profess to be a
Zoroastrian Mazdayaçna (worshiper of Ahura-Mazda), an
enemy of the Devas, and a devotee to Ahura, a praiser of
the immortal saints (Amesha-çpentas), a worshiper of the
immortal saints. I ascribe all good things to Ahura-Mazda,
who is good, and has good, who is true, lucid, shining,
who is the originator of all the best things, of the spirit in
nature (gâus), of the growth in nature, of the luminaries
and the self-shining brightness which is in the luminaries.
2. "I choose (follow, profess) the holy Ârmaiti, the good;
may she be mine! I abominate all fraud and injury
committed on the spirit of earth, and all damage and
destruction of the quarters of the Mazdayaçnas.
3. "I allow the good spirits who reside on this earth in
the good animals (as cows, sheep, &c.), to go and roam
about free according to their pleasure. I praise, besides,
all that is offered with prayer to promote the growth of
life. I shall cause neither damage nor destruction to the
quarters of the Mazdayaçnas, neither with my body nor
my soul.
4. "I forsake the Devas, the wicked, bad, false, untrue,
the originators of mischief, who are most baneful,
destructive, the basest of all beings. I forsake the Devas
and those who are Devas-like, the witches and their like,
and any being whatever of such a kind. I forsake them
with thoughts, words and deeds: I forsake them hereby
publicly, and declare that every lie and falsehood is to be
done away with.
5, 6. "In the same way as Zarathustra at the time when
Ahura-Mazda was holding conversations and meetings
with him, and both were conversing with each other,
forsook the Devas; so do I forsake the Devas, as the holy
Zarathustra did.
7. "To that party to which the waters belong, to
whatever party the trees, and the animating spirit of
nature, to that party to which Ahura-Mazda belongs, who
has created this spirit and the pure man; to that party of
which Zarathustra, and Kava Vistâçpa and Frashaostra and
Jâmâçpa were, of that party of which all the ancient fire-
priests (Soshyañto) were, the pious, who were spreading
the truth: of the same party and creed am I.
8. "I am a Mazdayaçna, a Zoroastrian Mazdayaçna. I
profess this religion by praising and preferring it to others
(the Deva religion). I praise the thought which is good, I
praise the word which is good, I praise the work which is
good.
9. "I praise the Mazdayaçna religion, and the pure
brotherhood which it establishes and defends against
enemies, the Zoroastrian Ahura religion, which is the
greatest, best, and most prosperous of all that are, and
that will be. I ascribe all good to Ahura-Mazda. This shall
be the praise (profession) of the Mazdayaçna religion."

Subdivision 4.—The Younger Yaçna, and Vispered.

While the Gâthâs and the confession just quoted represent the
most ancient phase of the Mazdayaçna faith, we enter, in the
remaining portion of the Yaçna, on a much later stage of the
growing creed. So many new divinities, or at any rate, objects of
reverential addresses, now enter upon the scene, that we almost
lose sight of Ahura-Mazda in the throng of his attendants. We seem
to be some ages away from the days when Zarathustra bade his
hearers choose between the one true God and the multitude of false
gods worshiped by his enemies. Ahura-Mazda is safely enthroned,
and Zarathustra shines out gloriously as his prophet; but
Zarathustra's creed is overloaded with elements of which he himself
knew nothing. The first chapter of the Yaçna, a liturgical prayer,
brings these elements conspicuously before us. It is an invocation
and celebration of a great variety of powers belonging to what is
termed the good creation, or the world of virtuous beings and good
things, as opposed to the malicious beings and bad things who form
the realm of evil.[74] Thus it opens:—
"I invoke and I celebrate the creator Ahura-Mazda,
luminous, resplendent, very great and very good, very
perfect and very energetic, very intelligent and very
beautiful, eminent in purity, who possesses the excellent
knowledge, the source of pleasure; him who has created
us, who has formed us, who has nourished us, the most
accomplished of intelligent beings."[75]
Every verse, until we approach the end, commences with the
same formula:—"I invoke and I celebrate;" or, as Spiegel translates
it, "I invite and announce it;" the sole difference is in the beings
invoked. Many of these are powers of more or less eminence in the
Parsee spiritual hierarchy, but it would be going beyond our object
here to enumerate their names and specify their attributes. To a
large proportion of them the epithets "pure, lord of purity," are
added, while some are dignified with more special titles of honor.
After the above homage to Ahura-Mazda, the writer invokes and
celebrates, among others: Mithra (a very famous god), who
increases oxen, who has one thousand ears, and ten thousand eyes;
the fire of Ahura-Mazda; the water given by Ahura-Mazda; the
Fravashis (angels or guardian spirits) of holy men and of women
who are under men's protection; energy, with a good constitution
and an imposing figure; victory given by Ahura; the months; the
new moon; the full moon; the time of fecundation; the years; all the
lords of purity, and thirty-three genii surrounding Hâvani, who are of
admirable purity, whom Mazda has made known, and Zarathustra
has proclaimed; the stars, especially a star named Tistrya; the
moon, which contains the germ of the ox; the sun, the eye of Ahura-
Mazda; the trees given by Mazda; the Word made known by
Zarathustra against the Devas; the excellent law of the
Mazdayaçnas; the perfect benediction; the pure and excellent man;
these countries and districts; pastures and houses; the earth, the
sky, the wind; the great lord of purity; days, months, and seasons;
the Fravashis of the men of ancient law; those of contemporaries
and relations, and his own; all genii who ought to be invoked and
adored. It is manifest from this invocation, in which I have omitted
many names and many repetitions, how far we are from the stern
and earnest simplicity of the Gâthâs. Regular liturgical forms have
sprung up, and these express the more developed and complicated
worship which the Parsee priesthood has now engrafted on the
Zarathustrian monotheism.
The concluding verses run as follows:—
"O thou who art given in this world, given against the
Devas, Zarathustra[76] the pure, lord of purity, if I have
wounded thee, either in thought, word, or deed,
voluntarily or involuntarily, I again address this praise in
thine honor; yes, I invoke thee if I have failed against
thee in this sacrifice and this invocation.
"O all ye very great lords, pure, masters of purity, if I
have wounded you, &c. [as above].
"May I, a worshiper of Mazda, an adherent of
Zarathustra, an enemy of the Devas, an observer of the
precepts of Ahura, address my homage to him who is
given here, given against the Devas; to Zarathustra, pure,
lord of purity, for the sacrifice, for the invocation, for the
prayer that renders favorable, for the benediction. (May I
address my homage) to the lords (who are) the days, the
parts of days, &c., for the benediction; that is to say: (may
I address my homage) to the lords (who are) the days,
the parts of days, the months, the seasons of the year
(Gahanbârs), the years; for the sacrifice, for the
invocation, for the prayer that renders favorable, for the
benediction."[77]
The rest of the Yaçna consists mainly of praises or prayers
addressed to the very numerous objects of Parsee adoration, and
most of it is of little interest. The following short section, however,
deserves remark:—
Yaçna 12.
1. "I praise the thoughts rightly thought, the words
rightly spoken, and the deeds rightly done.
2. "I seize upon (or resort to) all good thoughts, words
and deeds.
3. "I forsake all bad thoughts, words, and deeds.
4. "I bring you, O Amesha-çpentas,
5. "Praise and adoration,
6. "With thoughts, words, and deeds, with heavenly
mind, the vital force from my own body."[78]
In the following verses again there is some excellence:—
1. "May that man attain that which is best who teaches
us the right way to our profit in this world, both the
material and the spiritual world, the plain way that leads
to the worlds where Ahura is enthroned, and the sacrificer,
resembling thee, a sage, a saint, O Mazda.
2. "May there come to this dwelling contentment,
blessing, fidelity, and the wisdom of the pure."
8. "In this dwelling may Çraosha[79] (obedience) put an
end to disobedience, peace to strife, liberality to avarice,
wisdom to error, truthful speech to lying, which detests
purity" (Av. ii. 186, 187.—Yaçna 59).
The prominent position occupied by fire in the Parsee faith is well
known. The presence of fire is indeed an essential part of their
ritual, in which it is treated with no less honor than the consecrated
wafer in that of Catholic Christians. Not only, however, is it employed
in their rites, but it is addressed as an independent being, to whom
worship is due. Not that its place in the hierarchy is to be
confounded with that of Ahura-Mazda. It is not put upon a level with
the supreme being, but it is addressed as his son, its rank being thus
still more closely assimilated to that of the host, which is in like
manner a part of the liturgical machinery and an embodiment of the
son of God. A special chapter of the Yaçna—the 61st—is devoted to
Fire, and a summary of its contents will help us to understand the
light in which this deity was regarded.
The sacrificer begins by vowing offerings and praise and good
nourishment to "Fire, son of Ahura-Mazda." He trusts that Fire may
ever be provided with a proper supply of wood, and may always
burn brightly in this dwelling, even till the final resurrection. He
beseeches Fire to give him much property, much distinction,
holiness, a ready tongue, wit and understanding, activity,
sleeplessness, and posterity. Fire is said to await nourishment from
all; whoever comes, he looks at his hands, saying: "What does the
friend bring his friend, the coming one to him who sits alone?" And
this is the blessing he bestows on him who brings him dry wood,
picked out for burning: "Mayest thou be surrounded with herds of
cattle, with abundance of men. May it be with thee according to the
desire of thy heart, according to the desire of thy soul. Be joyous,
live thy life the whole time that thou shalt live."[80]
The last chapter but one of the Yaçna is a hymn in universal praise
of the good creation. All the objects belonging to that creation—that
is, made by Ahura-Mazda, and standing in contrast with the bad
creation of Agra-Mainyus—are enumerated, and as a catalogue of
these the hymn is interesting. Ahura-Mazda himself is named first;
then Zarathustra; after this follows the Fravashi (angel) of
Zarathustra, the Amesha-çpentas, the Fravashis of the pure, and so
forth, through a long list of animate and inanimate beings. Each is
named with the formula "we praise" following the title, as: "The
whole earth we praise" (Av., vol. ii. p. 202.—Yaçna, 70).
So close is the resemblance between the Vispered and that
portion of the Yaçna which we have just examined, that it will be
needless to dwell upon the contents of the former. We may therefore
at once pass on to a very important section, for theological
purposes, of the Zend-Avesta, namely—

Subdivision 5.—Vendidad.

Totally unlike either the Yaçna, the Vispered, or the Yashts, the
Vendidad is a legislative code—dealing indeed largely with religious
questions, but not confining itself exclusively to them. It differs from
the remainder of the sacred volume much as Leviticus differs from
the Psalms, or as the Institutes of Menu differ from the hymns of the
Rig-Veda. It is regarded as equally holy with the rest of the Avesta,
and is recited in divine service along with Vispered and Yaçna, the
three together forming what is termed the Vendidad-Sade (Av., ii.
lxxv). Its abrupt termination indicates that the code is not before us
in its entirety; the portion which has been preserved, however, does
not appear to have suffered great mutilation. Let us briefly
summarize its contents, first premising that the form they assume
(with trifling exceptions) is that of conversations between Ahura-
Mazda and his prophet.
The first Fargard (or chapter) is an enumeration of the good
countries or places created by Ahura-Mazda, and of the evils—such
as the serpent, the wasp, and various moral offenses, including that
of doubt—created in opposition to him in each case by the president
of the bad creation, Agra-Mainyus. The second Fargard is a long
narrative of the proceedings of a mythological hero named Yima (the
Indian Yama), to whom Ahura-Mazda is stated to have once
committed the government of the world, or of some part of it. Thus
far we have not entered on the proper subject-matter of the
Vendidad. The third Fargard, while still introductory, approaches
more nearly to the subsequent chapters, alike in its form and its
contents. In it Zarathustra lays certain queries before Ahura-Mazda,
and the replies given by that deity are of high importance for the
comprehension of both the social and moral status of the Parsees at
the time when this dialogue was written. The stress laid upon the
virtue of cultivating the soil is especially to be noticed. Similar
sentiments are frequently repeated in the Vendidad, and indicate a
people among whom agriculture was still in its infancy, the transition
from the pastoral state to the more settled condition of tillers of the
soil being still incomplete. The compilers of this code evidently felt
strongly the extreme value to their youthful community of
agricultural pursuits, and therefore encouraged them at every
convenient opportunity by representing them as peculiarly
meritorious in the sight of God.
Zarathustra begins his inquiries by asking what is in the first place
most agreeable to this earth, and successively ascertains what are
the five things which give it most satisfaction, and what the five
which cause it the most displeasure. Ahura-Mazda answers that, in
the first place, a holy man with objects of sacrifice is the most
agreeable; then a holy man making his dwelling-place, and storing it
with all that pertains to a happy and righteous life; then the
production of grain and of fruit trees, the irrigation of thirsty land, or
the drainage of moist land; fourthly, the breeding of live-stock and
draught-cattle; fifthly, a special incident connected with the presence
of such animals on the land. The five displeasing things are, the
meetings of Daevas and Drujus (evil spirits), the interment of men or
dogs (which was contrary to the law), the accumulation of Dakhmas,
or places where the bodies of the dead were left exposed, the dens
of animals made by Agra-Mainyus, and lastly, unbecoming conduct
on the part of the wife or son of a holy man. Further questions are
then put as to the mode of conduct which wins the approbation of
the earth, and it is stated to consist in actions which tend to
counteract the evils above enumerated. In the course of these
replies occasion is again taken to eulogize the man who vigorously
cultivates the soil, and to censure him who idly leaves it
uncultivated. Certain penalties are then imposed on those who bury
dogs or men, but the sin of leaving them underground for two years
is declared to be inexpiable, except by the Mazdayaçna Law, which
can purify the worst offenders:—
"For it (the Law) will take away these (sins) from those
who praise the Mazdayaçna Law, if they do not again
commit wicked actions. For this the Mazdayaçna Law, O
holy Zarathustra, takes away the bonds of the man who
praises it. It takes away deceit. It takes away the murder
of a pure man. It takes away the burial of the dead. It
takes away inexpiable actions. It takes away accumulated
guilt. It takes away all sins which men commit" (Av., vol. i.
p. 87, 88.—Vendidad, iii. 140-148).
We see from this that the power of the Law to deliver sinners from
the burden of their offenses was in no way inferior to that of the
Atonement of Christ.
It is unnecessary to dwell upon the fourth Fargard, which deals
with the penalties—consisting mainly of corporal punishment—for
breach of contract and other offenses. The fifth and sixth, being
concerned with the regulations to be observed in case of impurity
arising from the presence of dead bodies, are of little interest. A
large part of the seventh is occupied with the same subjects, but its
course is interrupted by certain precautions to be attended to in the
graduation of students of medicine, which may be commended to
the notice of other religious communities. Should a Mazdayaçna
desire to become a physician, on whom, inquires Zarathustra, shall
he first try his hand, the Mazdayaçna (orthodox Parsees), or the
Daevayaçnas (adherents of a false creed)? Ahura-Mazda replies that
the Daevayaçnas are to be his first patients. If he has performed
three surgical operations on these heretics, and his three patients
have died, he is to be held unfit for the medical profession, and must
on no account presume to operate on the adherents of the Law. If,
however, he is successful with the Daevayaçnas, he is to receive his
degree, and may proceed to practice on the more valuable bodies of
faithful Parsees. So careful a contrivance to ensure that none but
infidels shall fall victims to the knife of the unskilful surgeon evinces
no little ingenuity.
The eighth Fargard relates chiefly to the treatment of dead bodies,
while the ninth proceeds to narrate the rites for the purification of
those who have come in contact with them. A terrible penalty—that
of decapitation—is enacted against the man who ventures to
perform this rite without having learnt the law from a priest
competent to purify. The tenth Fargard prescribed the prayers by
which the Drukhs, or impure spirit supposed to attach itself to
corpses, and to come from them upon the living, is to be driven
away: and the subject is continued in the eleventh, which contains
formularies for the purification of dwellings, fires, and other objects.
Along with injunctions as to the purification of houses where a death
has occurred, the twelfth Fargard informs its hearers how many
prayers they are to offer up for deceased relatives. The number
varies both according to their relationship, being highest for those
that are nearest akin, and according to their purity or sinfulness,
double as many being required for the sinful as for the pure. After a
short introduction expounding the merit of killing a certain species of
animal and the demerit of killing another (what they are is
uncertain), the thirteenth Fargard proceeds to enumerate in detail
the various kinds of offenses against dogs, and the corresponding
penalties. Dogs were evidently of the utmost importance to the
community, and their persons are guarded with scarcely less care
than those of human beings. They are held to have souls, which
migrate after their decease to a canine Paradise. It seems, too, that
shades of departed dogs are appointed to watch the dangerous
bridge over which men's souls must travel on the road to felicity, and
which the wicked cannot pass; for we are informed of the soul of a
man who has killed a watch-dog, that "the deceased dogs who
guard against crime and watch the bridge do not make friends with
it on account of its abominable and horrible nature" (Av., vol. i. p.
192.—Vendidad, xiii. 25); while a man who has killed a water-dog is
required to make "offerings for its pious soul for three days and
three nights" (Av., vol. i. p. 201.—Vendidad, xiii. 173). The place to
which the souls of these animals repair is termed "the water-
dwelling," and it is stated that two water-dogs meet them on their
arrival, apparently to welcome them to their aqueous heaven (Av.,
vol. i. p. 200.—Vendidad, xiii. 167). Not only killing dogs, but
wounding them or giving them bad food, are crimes to be severely
punished; and even in case of madness the dog's life is on no
account to be taken. On the contrary, the utmost care is to be taken,
by fastening him so as to prevent escape, that he should do himself
no injury, for if he should happen in his madness to fall into water
and die, the community will have incurred sin by the accident.[81]
The following verses convey an interesting notion of the esteem in
which the dog was held among the early Parsees. The speaker is
Ahura-Mazda:—
"I have created the dog, O Zarathustra, with his own
clothes and his own shoes; with a sharp nose and sharp
teeth; attached to mankind, for the protection of the
herds. Then I created the dog, even I Ahura-Mazda, with
a body capable of biting enemies. When he is in good
health, when he is with the herds, when he is in good
voice, O holy Zarathustra, there comes not to his village
either thief or wolf to carry off property unperceived from
the villages" (Av., vol. i. p. 197.—Vendidad, xiii. 106-113).
In the fourteenth Fargard, water-dogs are further protected
against wounds; while in the fifteenth, the preservation of the canine
species at large is ensured by elaborate enactments. To give a dog
bones which he cannot gnaw, or food so hot as to burn its tongue, is
a sin; to frighten a bitch in pup, as by clapping the hands, is likewise
to incur guilt; and they are gravely criminal who suffer puppies to
die from inattention. If born in camel-stalls, stables, or any such
places, it is incumbent on the proprietor to take charge of them; or,
if the litter should be at large, at least the nearest inhabitant is
bound to become their protector. Strangely intermingled with these
precautions are rules prohibiting cohabitation with women in certain
physical conditions, and enactments for the prevention of abortion,
and for ensuring the support of a pregnant girl by her seducer, at
least until her child is born. The crime of abortion is described in a
manner which curiously reveals the practices occasionally resorted to
by Parsee maidens. Should a single woman be with child, and say,
"The child was begotten by such and such a man"—
"If then this man says, 'Try to make friends with an old
woman and inquire of her; if then this girl does make
friends with an old woman, and inquire of her, and this old
woman brings Baga, or Shaêta, or Ghnâna, or Fraçpâta, or
any of the vegetable purgatives, saying, 'Try to kill this
child;' if then the girl does try to kill the child, then the
girl, the man, and the old woman are equally criminal."
Neither the sixteenth nor the seventeenth Fargard need detain us.
They relate, the one to the above-mentioned rules to be observed
towards women, the other to the disposal of the hair and nails,
which are held to pollute the earth. The eighteenth Fargard begins,
as if in the middle of a conversation, with an address by Ahura-
Mazda, on the characteristics of true and false priests, some, it
appears, having improperly pretended to the priesthood. After some
questions on other points of doctrine put by Zarathustra, we are
suddenly introduced to a conversation between the angel Çraosha
and the Drukhs, or evil spirit, in which the latter describes the
several offenses that cause her to become pregnant, or, in other
words, increase her influence in the world. After this interlude, we
return to Ahura-Mazda and Zarathustra. The prophet, having been
exhorted to put questions, inquires of his god who causes him the
greatest annoyance. Ahura-Mazda replies that it is "he who mingles
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like