Class Notes, 3/21/07, Operating Systems Hi, Jane. Thanks again for covering the class. One of the main techniques the students need to how to recognize when there is a cycle in a directed graph. (Not all of them have had Discrete Structures yet.) I introduced the concept to them this week, and I think they should be OK with it, but if they re not, maybe give them some more examples. I ve left a few spaces in the notes to add in some pictures. Most of the pictures are straight out of the book, but a few I ve indicated what changes to make. I hope this is all right. The sections I d like you to cover are 7.2.2, 7.5, 7.6 (if you have time). I ve already covered 7.1, 7.2.1, 7.3, 7.4. The banker s algorithm has a lot of details, so if you get to that at the end of class, and have little time left, you can just let them go early. Background A process is a program in the process of being executed on the computer. Often, processes require exclusive use of resources at different points in their execution (resources may be e.g. printers, disk drives, files, or even variables shared among different processes). Exclusive use (mutual exclusion) means that only one process can use a given resource at one time. When a process P needs more than one resource R and R, then it may hold one resource R when it becomes available and at the same time P may have to wait for R, which is held by another process. Deadlock happens e.g. in the following circumstance. Assume P 0 is holding resource R 0 and waiting for R 1, and P 1 is holding R 1 and waiting for R 0. Then neither process can acquire all the resources it needs to continue executing, and there is a deadlock (unless one is preempted i.e., is forced to release a held resource).
7.2.2, Resource Allocation Graphs A resource allocation graph has two types of vertices, processes P i, represented by circles, and resources R j represented by rectangles. It may happen that there is more than one instance of a given resource e.g., two identical disk drives. (Different instances of a given resource must be logically and functionally interchangeable: so 2 printers in different wings of a building would generally be considered separate resources, not as 2 instances of the same resource.) Each instance of a resource R j is represented by a dot inside the R j rectangle. There are two types of directed edges (arrows) in a resource allocation graph: P i R j is a request edge, meaning that P i is requesting to use an instance of R j. A directed edge R j P i is an assignment edge, which means that an instance of R j is assigned (held) by P i. Request edges go from the circle P i to the rectangle R j, but assignment edges go from one of the dots inside the rectangle R j to P i (this represents the particular instance of R j which is being held). Do the example for figure 7.2. Note there is no cycle in the graph. Resource allocation graphs can change over time. When
a process has all the resources it needs, then we assume that the process will use these resources to complete its task and then release them. When a resource is released, the assignment edge is erased. For example, in figure 7.2, P 3 is not waiting for any other resource other than the R 3 which it holds. So, once it is finished with R 3, the edge R 3 P 3 can be erased. (Draw graph) A resource allocation graph can also change when a process s request for a resource is granted. In this case, a request edge becomes an assignment edge (so the direction of the arrow is switched). Continuing our example above, since R 3 is now available, P 2 s request can be granted, and R 3 can be assigned to P 2. (Draw graph) Now P 2 has all the resources it needs, and so, once it s through, it can release R 1, R 3, and its instance of R 2. Then P 1 can be assigned R 1 and execute, and all of
the processes are allowed to finish: there is no deadlock. Note how the graph changed: Since there was no cycle at the beginning, the graph could be unwound from P 3 to P 2 to P 1. (Draw a few subsequent graphs) (Another way a resource allocation graph can change is if a process requests another resource (so a new request edge appears). For now, we re concerned mainly with analyzing the current state of holds & requests, not anticipating future requests that will come in 7.5 below.) Cycles & Deadlocks If there is a cycle in the resource allocation graph, then there may or may not be a deadlock (at least in the case where there are multiple instances of some resources). If there is no cycle in the resource allocation graph, then there is no deadlock. Do the example for Figure 7.3. Explain why there is
a deadlock. Do the example for Figure 7.4. Even though there is a cycle, eventually P 2 will release its instance of R 1, which can then be assigned to P 1, breaking the cycle. Draw (at least part of) a possible evolution over time of the graph on the board, until it s obvious enough that all processes can complete their tasks. 7.5.1 Safe states Draw the Venn diagram on p. 257. A safe state is one in which it is always possible (given current requests & holds) to avoid deadlock. An unsafe state may or may not be deadlocked. If we have an algorithm to ensure that the system is always in a safe state, then we can guarantee not to have deadlocks. Our deadlock avoidance algorithms depend on knowing the maximum needs of each process. So a process P may currently need 5 tape drives, but at some point
in the future may need a total of 10 tape drives. Its maximum needs are then 10 tape drives. A safe sequence is a sequence of processes P 1,... P n so that P 1 can acquire its maximum resources from the sum of those already held by (allocated to) it & those that are currently free for the system to allocate. Then a subsequent process in the sequence P i must have its maximum needs satisfied by the sum of the resources allocated to P 1,..., P i plus those free in the system. This is a reasonable definition, since the processes P 1,... P n can be executed in this order. So P 4 is allowed to use the resources of P 1, P 2, P 3, since we may assume that P 1, P 2, P 3 have already completed their tasks and have released their resources to the system. Consider the following example, in which P 0, P 1, P 2 need a certain number of tape drives. Assume there are a total of 10 tape drives in the system. The beginning state is 3 free, Process Maximum Needs Current Allocation P 0 10 5 P 1 4 2 P 2 9 2 Then P 1, P 0, P 2 is a safe sequence, since, conceptually, we may think of executing them in that order: 3 free, Process Maximum Needs Current Allocation P 0 10 5 P 1 4 2 P 2 9 2 P 1 can then acquire 2 free drives from the system. Once
P 1 finishes, the state is 5 free, Process Maximum Needs Current Allocation P 0 10 5 P 2 9 2 Now, conceptually, P 0 can acquire the 5 free drives and execute, leaving 10 free, Process Maximum Needs Current Allocation P 2 9 2 And finally P 2 can execute. Consider what would happen if we initially allocate one more drive to P 2. Then the state would be 2 free, Process Maximum Needs Current Allocation P 0 10 5 P 1 4 2 P 2 9 3 the same process leads to a possible deadlock (P 1 executes, leaving 4 free drives, but this is not enough, since P 0 may request 5, and P 2 may request 6 at the same time). Thus it is a mistake to allocate an additional drive to P 2 at the beginning, since that will become an unsafe state. 7.5.2, Resource-Allocation-Graph Algorithm for Deadlock Avoidance In the case that each resource R i has exactly one instance, we can omit the dots inside the rectangle R i, and simply draw a more traditional graph.
The following resource-allocation-graph algorithm only works in the case that each resource has exactly one instance. We introduce a new type of edge to the resourceallocation graph above, called a claim edge. A claim edge P i R j, is drawn with a dotted arrow, and indicates that at some point in the future, P i may request to use R j. (So P i s maximum need for R j is 1, but its current allocation & request for R j is 0). Note that a claim edge is drawn in the same direction as a request edge, since it represents a potential request. A system in which all resources have a single instance is in an unsafe state exactly when there is a cycle in its resource-allocation graph (as augmented here with claim edges). Do the example of figures 7.6, 7.7. Note that 7.7 is an unsafe state, but not a deadlock. This is because the claim edge P 1 R 2 is only a potential request, not an actual request. It is an unsafe state, since if P 1 requests R 2, then there will be an actual deadlock.
7.6.1 Resource-Allocation-Graph Algorithm for Deadlock Detection Assume we are still in the case where there is only one instance of each resource. Then we can use the resourceallocation-graph algorithm to detect whether there is currently a deadlock in the system. Since we are now only concerned whether the system is deadlocked, not whether it is in a safe state, there are no claim edges for anticipating future problems, only assignment & request edges. For a system in which each resource has only one instance, there is a deadlock exactly when there is a cycle in the resource allocation graph. (Note this algorithm is exactly the same as the case for Deadlock Avoidance above, the only difference being that we consider only actual, current requests, and not potential, future ones.) Write example 7.8.a. In the case where each resource has only one instance, it is also useful to write down an auxiliary graph, the wait-for graph. This graph is formed from the resourceallocation graph by using only the processes as nodes in the new graph, and by drawing an arrow between processes P i P j only when there is a path P i R k P j
that passes through a single resource R k. Recall that this means that P j is holding R k, and P i is requesting R k. This means that P i is waiting for P j to release R k. Write down example 7.8.b. The wait-for graph is less complicated than the resourceallocation graph, and (in the current case each resource has 1 instance) there is a cycle in the wait-for graph exactly when (if and only if) there is a cycle in the resourceallocation graph. The wait-for graph then provides an easier way to check for deadlocks (cycles). Why is it not justified to use the wait-for graph in the case of multiple instances of a resource? Consider two instances of a resource R, one held by P 0, and the other by P 1. If P 2 requests an instance of R, then we have (Draw a small piece of a graph with two arrows coming from the dots in R to each of P 0 and P 1, and an arrow coming from P 2 to R.) Now P 2 is waiting for either P 0 or P 1 to finish, and
not for P 0 or P 1 individually (one arrow in wait-for graph P 2 P 0 or P 2 P 0 ), and also not for both P 0 and P 1 at once (two arrows in the wait-for graph). So it s not appropriate to reduce the resource-allocation graph to a wait-for graph. Another example (Dining Philosophers, Chapter 6) (Jane: they ve already seen this example: the new part is drawing the graph.) Recall the dining philosophers problem: 5 philosophers P 0,..., P 4 sit around a round table eating & thinking. In the center of the table is a bowl of rice. There are only 5 chopsticks C 0,..., C 4 on the table, one chopstick in between each pair of philosophers. In order to eat, a philosopher P i must be able to take both the chopsticks on her left C i & right C (i+1)%5, in order to eat. (Jane: % means mod in C++) A deadlock is possible if each philosopher P i, upon getting hungry, first attempts to pick up her left chopstick C i and then attempts to pick up her right chopstick C (i+1)%5. If they all pick up the left chopstick at once, then none of them can pick up the right chopstick, and there is a deadlock. (Jane: I didn t copy chapter 6 for myself, so I m not 100% sure the picture I ve described is exactly the same as the one in the book in terms of numbering the chopsticks.) In this case, the wait-for graph consists of a single cycle P 0 P 1 P 2 P 3 P 4 P 0.
Vector Math If X = (1, 3, 4, 7) and Y = (0, 2, 4, 5) are integer 4- dimensional vectors, then we say their difference X Y = (1 0, 3 2, 4 4, 7 5) = (1, 1, 0, 2) So the difference of two vectors is a vector whose components are the differences of the components. (We saw in class a vector sum works similarly.) Matrix addition and substraction work the same way. If X and Y are two vectors of length n, then we say X Y if and only if the components X[i] Y [i] for all i = 1,..., n. For example, (0, 2, 4, 5) (1, 3, 4, 7), but (1, 0, 0, 0) (0, 1000, 100000, 100000). We say X < Y if X Y but X Y. So (0, 2, 4, 5) < (1, 3, 4, 7). (For those students who have taken Discrete Structures, the definition of for vectors is the product partial order on the set of integral vectors Z n = Z Z.) Banker s Algorithm There are actually 3 slightly different settings in which we can apply the banker s algorithm. They all are for analyzing systems which have resources with multiple instances. The safety algorithm (7.5.3.1) determines whether the system is in a safe state. The resource-request algorithm (7.5.3.2) determines whether a given request can be safely granted (i.e. will leave the system in a safe state). Finally, in 7.6.2, the banker s algorithm can be used to detect a deadlock when there are resources with multiple instances. (Safety Algorithm) We have the following data:
n processes P 0,..., P n 1, m resources R 0,... R m 1. Available is a vector of m nonnegative integers, representing the number of instances of each resource which are available to be assigned to any process. Available[j] is the number of instances of R j available. Max is an n m matrix. Max[i][j] represents the maximum number of instances of resource R j which process P i may request. Allocation is an n m matrix. Allocation[i][j] is the number of instances of R j currently held by (allocated to) P i. Let Allocation i denote the row of Allocation consisting of the allocation of process P i. We also need three auxiliary structures: Need is an n m matrix representing the maximum number of additional resources each process may need. Need = Max Allocation. Let Need i denote the row of Need consisting of the needs of process P i. Work, an m-vector of integers. Initialize W ork = Available. An n-vector Finish of boolean flags. Initialize F inish[i] = false. The algorithm is as follows: (Jane: == means test for equality, while = means assignment. So if x is a variable with current value 2, then x = x + 2 assigns x
the new value 4, while x == x + 2 is false as a Boolean expression.) 1. If possible, find an i so that both F inish[i] == false and Need i W ork. If not possible, go to step 3. 2. Assign W ork = W ork+allocation i. Assign F inish[i] = true. Go back to step 1. 3. If F inish[i] == true for all i, then the system is in a safe state (and the order in which we processed the P i s is a safe sequence). If one or more of the F inish[i] s is false, then we are in an unsafe state. Example. Consider resources A, B, C and processes P 0, P 1, P 2. Assume we have the following initial data (Need is calculated from Allocation & Max): Process Allocation Max Need Available A B C A B C A B C A B C P 0 1 0 2 3 3 3 2 3 1 4 1 2 P 1 0 0 1 0 2 6 0 2 5 P 2 0 2 2 2 2 2 2 0 0 Then the Banker s Algorithm finds that P 2, P 0, P 1 is a safe sequence, and we are in a safe state. Why? Initialize W ork = Available. P 2 is the only process with Need 2 W ork, so initially i = 2. After we process P 2, we have Process Allocation Max Need Work A B C A B C A B C A B C P 0 1 0 2 3 3 3 2 3 1 4 3 4 P 1 0 0 1 0 2 6 0 2 5 (We ve erased P 2, since it is finished, and we have added the resources of P 2 to W ork.) Now Need 0
W ork, and so we can choose i = 0. After P 0 is finished, we have Process Allocation Max Need Work A B C A B C A B C A B C P 1 0 0 1 0 2 6 0 2 5 5 3 6 Now Need i W ork, and we can finish with P 1. More? If you have extra time (which I doubt), you can cover 7.5.3.2 (a small modification of the above algorithm), and the example 7.5.3.3 in the book. Thanks again, John