- •Preface
- •Contents
- •1.1 What Operating Systems Do
- •1.2 Computer-System Organization
- •1.4 Operating-System Structure
- •1.5 Operating-System Operations
- •1.6 Process Management
- •1.7 Memory Management
- •1.8 Storage Management
- •1.9 Protection and Security
- •1.10 Kernel Data Structures
- •1.11 Computing Environments
- •1.12 Open-Source Operating Systems
- •1.13 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •2.3 System Calls
- •2.4 Types of System Calls
- •2.5 System Programs
- •2.6 Operating-System Design and Implementation
- •2.9 Operating-System Generation
- •2.10 System Boot
- •2.11 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •3.1 Process Concept
- •3.2 Process Scheduling
- •3.3 Operations on Processes
- •3.4 Interprocess Communication
- •3.5 Examples of IPC Systems
- •3.7 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •4.1 Overview
- •4.2 Multicore Programming
- •4.3 Multithreading Models
- •4.4 Thread Libraries
- •4.5 Implicit Threading
- •4.6 Threading Issues
- •4.8 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •5.1 Background
- •5.3 Peterson’s Solution
- •5.4 Synchronization Hardware
- •5.5 Mutex Locks
- •5.6 Semaphores
- •5.7 Classic Problems of Synchronization
- •5.8 Monitors
- •5.9 Synchronization Examples
- •5.10 Alternative Approaches
- •5.11 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •6.1 Basic Concepts
- •6.2 Scheduling Criteria
- •6.3 Scheduling Algorithms
- •6.4 Thread Scheduling
- •6.5 Multiple-Processor Scheduling
- •6.6 Real-Time CPU Scheduling
- •6.8 Algorithm Evaluation
- •6.9 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •7.1 System Model
- •7.2 Deadlock Characterization
- •7.3 Methods for Handling Deadlocks
- •7.4 Deadlock Prevention
- •7.5 Deadlock Avoidance
- •7.6 Deadlock Detection
- •7.7 Recovery from Deadlock
- •7.8 Summary
- •Practice Exercises
- •Bibliography
- •8.1 Background
- •8.2 Swapping
- •8.3 Contiguous Memory Allocation
- •8.4 Segmentation
- •8.5 Paging
- •8.6 Structure of the Page Table
- •8.7 Example: Intel 32 and 64-bit Architectures
- •8.8 Example: ARM Architecture
- •8.9 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •9.1 Background
- •9.2 Demand Paging
- •9.3 Copy-on-Write
- •9.4 Page Replacement
- •9.5 Allocation of Frames
- •9.6 Thrashing
- •9.8 Allocating Kernel Memory
- •9.9 Other Considerations
- •9.10 Operating-System Examples
- •9.11 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •10.2 Disk Structure
- •10.3 Disk Attachment
- •10.4 Disk Scheduling
- •10.5 Disk Management
- •10.6 Swap-Space Management
- •10.7 RAID Structure
- •10.8 Stable-Storage Implementation
- •10.9 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •11.1 File Concept
- •11.2 Access Methods
- •11.3 Directory and Disk Structure
- •11.4 File-System Mounting
- •11.5 File Sharing
- •11.6 Protection
- •11.7 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •12.2 File-System Implementation
- •12.3 Directory Implementation
- •12.4 Allocation Methods
- •12.5 Free-Space Management
- •12.7 Recovery
- •12.9 Example: The WAFL File System
- •12.10 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •13.1 Overview
- •13.2 I/O Hardware
- •13.3 Application I/O Interface
- •13.4 Kernel I/O Subsystem
- •13.5 Transforming I/O Requests to Hardware Operations
- •13.6 STREAMS
- •13.7 Performance
- •13.8 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •14.1 Goals of Protection
- •14.2 Principles of Protection
- •14.3 Domain of Protection
- •14.4 Access Matrix
- •14.5 Implementation of the Access Matrix
- •14.6 Access Control
- •14.7 Revocation of Access Rights
- •14.8 Capability-Based Systems
- •14.9 Language-Based Protection
- •14.10 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •15.1 The Security Problem
- •15.2 Program Threats
- •15.3 System and Network Threats
- •15.4 Cryptography as a Security Tool
- •15.5 User Authentication
- •15.6 Implementing Security Defenses
- •15.7 Firewalling to Protect Systems and Networks
- •15.9 An Example: Windows 7
- •15.10 Summary
- •Exercises
- •Bibliographical Notes
- •Bibliography
- •16.1 Overview
- •16.2 History
- •16.4 Building Blocks
- •16.5 Types of Virtual Machines and Their Implementations
- •16.6 Virtualization and Operating-System Components
- •16.7 Examples
- •16.8 Summary
- •Exercises
- •Bibliographical Notes
- •Bibliography
- •17.1 Advantages of Distributed Systems
- •17.2 Types of Network-based Operating Systems
- •17.3 Network Structure
- •17.4 Communication Structure
- •17.5 Communication Protocols
- •17.6 An Example: TCP/IP
- •17.7 Robustness
- •17.8 Design Issues
- •17.9 Distributed File Systems
- •17.10 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •18.1 Linux History
- •18.2 Design Principles
- •18.3 Kernel Modules
- •18.4 Process Management
- •18.5 Scheduling
- •18.6 Memory Management
- •18.7 File Systems
- •18.8 Input and Output
- •18.9 Interprocess Communication
- •18.10 Network Structure
- •18.11 Security
- •18.12 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •19.1 History
- •19.2 Design Principles
- •19.3 System Components
- •19.4 Terminal Services and Fast User Switching
- •19.5 File System
- •19.6 Networking
- •19.7 Programmer Interface
- •19.8 Summary
- •Practice Exercises
- •Bibliographical Notes
- •Bibliography
- •20.1 Feature Migration
- •20.2 Early Systems
- •20.3 Atlas
- •20.7 CTSS
- •20.8 MULTICS
- •20.10 TOPS-20
- •20.12 Macintosh Operating System and Windows
- •20.13 Mach
- •20.14 Other Systems
- •Exercises
- •Bibliographical Notes
- •Bibliography
- •Credits
- •Index
7.6 Deadlock Detection |
333 |
The content of the matrix Need is defined to be Max − Allocation and is as follows:
|
Need |
|
A B C |
P0 |
7 4 3 |
P1 |
1 2 2 |
P2 |
6 0 0 |
P3 |
0 1 1 |
P4 |
4 3 1 |
We claim that the system is currently in a safe state. Indeed, the sequence < P1, P3, P4, P2, P0> satisfies the safety criteria. Suppose now that process P1 requests one additional instance of resource type A and two instances of resource type C, so Req uest1 = (1,0,2). To decide whether this request can be immediately granted, we first check that Req uest1 ≤ Available—that is, that (1,0,2) ≤ (3,3,2), which is true. We then pretend that this request has been fulfilled, and we arrive at the following new state:
|
Allocation |
Need |
Available |
||||
|
|
A B C |
|
A B C |
|
A B C |
|
P0 |
0 1 0 |
|
7 4 3 |
2 3 0 |
|
||
P1 |
3 0 2 |
|
0 2 0 |
|
|
|
|
P2 |
3 0 2 |
|
6 0 0 |
|
|
|
|
P3 |
2 1 1 |
|
0 1 1 |
|
|
|
|
P4 |
0 0 2 |
|
4 3 1 |
|
|
|
We must determine whether this new system state is safe. To do so, we execute our safety algorithm and find that the sequence < P1, P3, P4, P0, P2> satisfies the safety requirement. Hence, we can immediately grant the request of process P1.
You should be able to see, however, that when the system is in this state, a request for (3,3,0) by P4 cannot be granted, since the resources are not available. Furthermore, a request for (0,2,0) by P0 cannot be granted, even though the resources are available, since the resulting state is unsafe.
We leave it as a programming exercise for students to implement the banker’s algorithm.
7.6Deadlock Detection
If a system does not employ either a deadlock-prevention or a deadlockavoidance algorithm, then a deadlock situation may occur. In this environment, the system may provide:
•An algorithm that examines the state of the system to determine whether a deadlock has occurred
•An algorithm to recover from the deadlock
334 |
Chapter 7 Deadlocks |
P5
|
R1 |
|
R3 |
|
R4 |
|
|
|
|
|
|
P5
P1 |
P2 |
P3 |
P1 |
P2 |
P3 |
|
P4 |
|
P4 |
R2 |
|
|
|
R5 |
|||
|
(a) |
|
(b) |
Figure 7.9 (a) Resource-allocation graph. (b) Corresponding wait-for graph.
In the following discussion, we elaborate on these two requirements as they pertain to systems with only a single instance of each resource type, as well as to systems with several instances of each resource type. At this point, however, we note that a detection-and-recovery scheme requires overhead that includes not only the run-time costs of maintaining the necessary information and executing the detection algorithm but also the potential losses inherent in recovering from a deadlock.
7.6.1 Single Instance of Each Resource Type
If all resources have only a single instance, then we can define a deadlockdetection algorithm that uses a variant of the resource-allocation graph, called a wait-for graph. We obtain this graph from the resource-allocation graph by removing the resource nodes and collapsing the appropriate edges.
More precisely, an edge from Pi to Pj in a wait-for graph implies that process Pi is waiting for process Pj to release a resource that Pi needs. An edge Pi → Pj exists in a wait-for graph if and only if the corresponding resourceallocation graph contains two edges Pi → Rq and Rq → Pj for some resource Rq . In Figure 7.9, we present a resource-allocation graph and the corresponding wait-for graph.
As before, a deadlock exists in the system if and only if the wait-for graph contains a cycle. To detect deadlocks, the system needs to maintain the waitfor graph and periodically invoke an algorithm that searches for a cycle in the graph. An algorithm to detect a cycle in a graph requires an order of n2 operations, where n is the number of vertices in the graph.
7.6.2Several Instances of a Resource Type
The wait-for graph scheme is not applicable to a resource-allocation system with multiple instances of each resource type. We turn now to a deadlock-
7.6 Deadlock Detection |
335 |
detection algorithm that is applicable to such a system. The algorithm employs several time-varying data structures that are similar to those used in the banker’s algorithm (Section 7.5.3):
•Available. A vector of length m indicates the number of available resources of each type.
•Allocation. An n × m matrix defines the number of resources of each type currently allocated to each process.
•Request. An n × m matrix indicates the current request of each process. If Request[i][j] equals k, then process Pi is requesting k more instances of resource type Rj .
The ≤ relation between two vectors is defined as in Section 7.5.3. To simplify notation, we again treat the rows in the matrices Allocation and Request as vectors; we refer to them as Allocationi and Requesti . The detection algorithm described here simply investigates every possible allocation sequence for the processes that remain to be completed. Compare this algorithm with the banker’s algorithm of Section 7.5.3.
1.Let Work and Finish be vectors of length m and n, respectively. Initialize
Work = Available. For i = 0, 1, ..., n – 1, if Allocationi = 0, then Finish[i] = false. Otherwise, Finish[i] = true.
2.Find an index i such that both
a.Finish[i] == false
b.Requesti ≤ Work
If no such i exists, go to step 4.
3.Work = Work + Allocationi Finish[i] = true
Go to step 2.
4.If Finish[i] == false for some i, 0 ≤ i < n, then the system is in a deadlocked state. Moreover, if Finish[i] == false, then process Pi is deadlocked.
This algorithm requires an order of m × n2 operations to detect whether the system is in a deadlocked state.
You may wonder why we reclaim the resources of process Pi (in step 3) as soon as we determine that Requesti ≤ Work (in step 2b). We know that Pi is currently not involved in a deadlock (since Requesti ≤ Work). Thus, we take an optimistic attitude and assume that Pi will require no more resources to complete its task; it will thus soon return all currently allocated resources to the system. If our assumption is incorrect, a deadlock may occur later. That deadlock will be detected the next time the deadlock-detection algorithm is invoked.
To illustrate this algorithm, we consider a system with five processes P0 through P4 and three resource types A, B, and C. Resource type A has seven instances, resource type B has two instances, and resource type C has six
336 |
Chapter 7 Deadlocks |
|
|
|
|
|
|
|
|
|
instances. Suppose that, at time T0, we have the following resource-allocation |
||||||||
|
state: |
|
|
|
|
|
|
|
|
|
|
Allocation |
Request |
Available |
|||||
|
|
|
A B C |
|
A B C |
|
|
A B C |
|
|
P0 |
0 1 0 |
0 0 0 |
|
0 0 0 |
|
|||
|
P1 |
2 0 0 |
2 0 2 |
|
|
|
|
||
|
P2 |
3 0 3 |
0 0 0 |
|
|
|
|
||
|
P3 |
2 1 1 |
1 0 0 |
|
|
|
|
||
|
P4 |
0 0 2 |
0 0 2 |
|
|
|
|
We claim that the system is not in a deadlocked state. Indeed, if we execute our algorithm, we will find that the sequence < P0, P2, P3, P1, P4> results in Finish[i] == true for all i.
Suppose now that process P2 makes one additional request for an instance of type C. The Request matrix is modified as follows:
|
Request |
||
|
|
A B C |
|
P0 |
0 0 0 |
|
|
P1 |
2 0 2 |
|
|
P2 |
0 0 1 |
|
|
P3 |
1 0 0 |
|
|
P4 |
0 0 2 |
|
We claim that the system is now deadlocked. Although we can reclaim the resources held by process P0, the number of available resources is not sufficient to fulfill the requests of the other processes. Thus, a deadlock exists, consisting of processes P1, P2, P3, and P4.
7.6.3Detection-Algorithm Usage
When should we invoke the detection algorithm? The answer depends on two factors:
1.How often is a deadlock likely to occur?
2.How many processes will be affected by deadlock when it happens?
If deadlocks occur frequently, then the detection algorithm should be invoked frequently. Resources allocated to deadlocked processes will be idle until the deadlock can be broken. In addition, the number of processes involved in the deadlock cycle may grow.
Deadlocks occur only when some process makes a request that cannot be granted immediately. This request may be the final request that completes a chain of waiting processes. In the extreme, then, we can invoke the deadlockdetection algorithm every time a request for allocation cannot be granted immediately. In this case, we can identify not only the deadlocked set of