Handout1

Embed Size (px)

DESCRIPTION

embedded

Citation preview

RESOURCE ACCESS CONTROL

Processes frequently need to communicate with other processes. Thus there is a need for communication between processes preferably in a well-structured way not using interrupts. Processes that are working together may share some common resources that each one can read and write. The location of the shared resources does not change the nature of the communication or the problems that arise.

When two or more process try to access shared resource, the final result depends on who runs precisely when. This may lead to Race condition or hazards and software behaves erratically. The key to prevent such situation here is to prohibit more than one process from accessing the shared resources. Put in other words, what we need is mutual exclusion-some way of making sure that if one process is using shared resources, the other processes will be excluded from doing the same thing.

The part of the program where process uses shared resources is called critical section. If we could arrange matters such that no two processes were ever in their critical regions at the same time, we could avoid race conditions.

1. Mutual Exclusion :

In this section we will examine various proposals for achieving mutual exclusion, so that while one process is busy updating shared memory in its critical region, no other process will enter its critical region and cause trouble.

1.1 Disable Interrupts :

The simplest solution is to disable interrupts before process enters critical section of memory so that it will finish execution of critical section without causing race condition. This approach is generally unattractive because it is unwise to give user processes the power to turn off interrupts. Suppose that one of them did it, and never turned them on again?1.2 Semaphore :

It acts as lock to shared resources. Once a process requests and acquires semaphore from RTOS, no other processes are granted semaphore and hence they prohibited from shared resources. 1.1.2 Binary Semaphore :

Consider having a single, shared, (semaphore) variable, initially 1. When a process wants to enter its critical region, it first tests the lock. If the lock is 1, the process sets it to 0 and enters the critical region. If the lock is already 0, the process just waits until it becomes 1. Thus, a 1 means that no process is in its critical region and a 0 means that some process is in its critical region.

(b) Counting Semaphore:

It uses integer semaphore variable which counts number of times it is released. It decrements when taken and increments when released by the process. Its value at any time is equal to initial value plus difference between number times it in released and number of times it is taken. It is uses two standard atomic functions called P or Wait and V or Signal.

Fig.2When process P1 executes P function before entering to critical region and if sem_1 < 0 than it means other process or processes have executed P already. Hence P1 is not allowed to enter critical section and is placed in wait queue. When a process P1 executes V function and if sem_1 is less than or equal to 0 than it means there are still pending (waiting) processes on this semaphore. Thus control is transferred to RTOS which will unblock one of the waiting processes (usually in FIFO manner). If sem_1 is positive (means no waiting process on semaphore) P1 is allowed to resume its execution.

(c) Taking Turn:

In fact, this solution requires that the two processes strictly alternate in entering their critical regions. In Fig. 3, the integer variable turn, initially 0 keeps track of whose turn it is to enter the critical region and examine or update the shared memory. Initially, process P0 inspects turn, finds it to be 0, and enters its critical region. Process P1 also finds it to be 0 and therefore sits in a tight loop (waiting) continually testing turn to see when it becomes 1. When

Fig.3process 0 leaves the critical region, it sets turn to 1 to allow process P1 to enter its critical region. Process P1 finishes its critical region, so both processes are in their noncritical regions, with turn set to 0. Suppose process P0 needs frequent execution (speedy) of whole loop quickly while P1 is very slow and takes long time to finish its turn. Once P0 finishes its turn, it has to wait long until P1 completes its execution and set turn to 1. This wastes CPU time and reduces throughput. Taking turns is not a good idea when one of the processes is much slower than the other. While this algorithm does avoid all races, it is not really a serious candidate.

(d) Peterson Algorithm:By combining the idea of taking turns with the idea of lock variables and warning variables Peterson proposed solution for mutual exclusion. Before using the shared variables (i.e., before entering its critical region), each process will have too wait, until it is safe to enter. After it has finished with the shared variables, the process calls leave-region to indicate that it is done and to allow the other process to enter, if it so desires.

Fig.4Let us see how this solution works. Initially neither process is in its critical region. Now processes P0 and P1 indicate their interest by setting its array element flag to 1. But the execution of critical region depends on who sets variable turn last. If P0 sets turn to 0 after P1 then P1 continues execution of critical section to use its turn. After executing critical section P1 resets its flag (i.e. flag[1]=0) and enters in non critical region.

Even if P1 is very slow process and takes very long time in doing non critical stuff, P0 is still allowed to be executed several times if P0 finishes loop faster. This is because P1 has already reset the flag[1] which prevent P0 to remain in while loop. So there is no strict alteration exist in executing processes (unlike taking turn method). Thus this algorithm works well even if execution time of processes may vary. It also ensure mutual exclusion (no race conditions).2. Priority Inversion :

When a low-priority process blocks a higher-priority one, a priority inversion is said to occur. Let three processes labeled as H, M and L have high, medium and lowest priority. The process H and L share a semaphore S. Assume that at time t1, process L is only ready run. Scheduler executes L and while running L has acquired the semaphore S. At time t2, H becomes ready and preempt L and attempt to use shared resources by locking S. Since lock S is currently with L, process H will be suspended (blocked) and L will continue its execution. As M is not sharing semaphore with either L or H, it preempts L and scheduler now runs process M at time t3. The process L gets blocked holding semaphore S. This leads to situation where high priority process H even if ready can not preempt low priority process M since H cant advance without semaphore S. The processes L cant release semaphore as it is blocked by M.This is the priority inversion where high priority process (H) is unduly prevented from execution by running process M who has lower priority than H.

Priority Inheritance:

The problem of priority inversion in real-time systems has been studied intensively for both fixed-priority and dynamic-priority scheduling. One result, the Priority Inheritance Protocol, offers a simple solution to the problem of unbounded priority inversion. In the Priority Inheritance Protocol the priority of processes are dynamically changed so that the priority of any process in a critical region gets the priority of the highest process pending on that same critical region. In particular, when a process, Pi, blocks one or more higher-priority processes, it temporarily inherits the highest priority of the blocked processes.

If a process, P1, is blocked by P2 and P1 > P2, (P1 has precedence over P2), process P2 inherits the priority of P1 as long as it blocks P1. When P2 exits the critical section that caused the block, it reverts to the priority it had when it entered that section.

Priority inheritance is transitive. If P3 blocks P2, which blocks P1 (with P1 > P2 > P3), then P3 inherits the priority of P1 via P2.

3. Deadlock:

Processes often need multiple shared resources (multiple semaphore) for servicing. Resources are of two types: A preemptable resource is one that can be taken away from the process owning it with no ill effects. A non preemptable resource, in contrast, is one that cannot be taken away from its current owner process. It can only be released explicitly by process holding it. In general, deadlocks involve non preemptable resources.Let process P1 and P2 shares resources R1 and R2. P1 acquires R1 during its execution. Later, P2 preempts P1 and acquires R2 during its execution. Now P2 needs R1 and P1 need R2 to go ahead. At this point both processes are blocked and will remain blocked forever. This situation is called a deadlock.

Deadlock can be defined formally as follows:

A set of processes is deadlocked if each process in the set is waiting for an event that only another process in the set can cause.

Because all the processes are waiting, none of them will ever cause any of the events that could wake up any of the other members of the set, and all the processes continue to wait forever.

In other words, each member of the set of deadlocked processes is waiting for a resource that is owned by a deadlocked process. None of the processes can run, none of them can release any resources, and none of them can be awakened. The number of processes and the number and kind of resources possessed and requested are unimportant.Coffman et al. (1971) showed that four conditions must hold for there to be a deadlock:

1. Mutual exclusion condition. Each resource is either currently assigned to exactly one process or is available.

2. Hold and wait condition. Processes currently holding resources granted earlier can request new resources.

3. No preemption condition. Resources previously granted cannot be forcibly taken away from a process. They must be explicitly released by the process holding them.

4. Circular wait condition. There must be a circular chain of two or more processes, each of which is waiting for a resource held by the next member of the chain.

3.1 Deadlock Modeling

Holt (1972) showed how these four conditions can be modeled using directed graphs. The graphs have two kinds of nodes: processes, shown as circles, and resources, shown as squares. An arc from a resource node (square) to a process node (circle) means that the resource previously has been requested by, granted to, and is currently held by that process. In Fig. 5(a), resource R is currently assigned to process A.

Fig. 5An arc from a process to a resource means that the process is currently blocked waiting for that resource. In Fig. 3-7(b) process B is waiting for resource S. In Fig. 5(c) we see a deadlock: process C is waiting for resource T, which is currently held by process D. Process D is not about to release resource T because it is waiting for resource U, held by C. Both processes will wait forever. A cycle in the graph means that there is a deadlock involving the processes and resources in the cycle.

Imagine that we have three processes, A, B, and C, and three resources, R, S, and T. The resource acquisition and requests of three processes are given in Fig. 6(e)-(j). After request 4 has been made, A blocks waiting for S, as shown in Fig. 6(h). In the next two steps B and C also block, ultimately leading to a cycle and the deadlock of Fig. 6(j).

Fig. 6

In Fig. 3-8, if the operating system knew about the impending deadlock, it could suspend B instead of granting it S. By running only A and C, we would get the requests and releases of Fig. 7(k) instead of Fig. 6(d). This sequence leads to the resource graphs of Fig, 7(l)-(q), which do not lead to deadlock.

Fig. 73.2 Detection and Recovery

A second technique is detection and recovery. When this technique is used, the system does not do anything except monitor the requests and releases of resources. Every time a resource is requested or released, the resource graph is updated, and a check is made to see if any cycles exist, If a cycle exists, one of the processes in the cycle is killed. If this does not break the deadlock, another process is killed, and so on until the cycle is broken.

A somewhat cruder method is to not even maintain the resource graph but instead periodically check to see if there are any processes that have been continuously blocked for more than say, 1 hour. Such processes are then killed.

Detection and recovery is the strategy often used on large mainframe computers, especially batch systems in which killing a process and then restarting it is usually acceptable. Care must be taken to restore any modified files to their original state, however, and undo any other side effects that may have occurred.

3.3 Deadlock Avoidance

In Fig. 6 we saw that deadlock was avoided not by imposing arbitrary rules on processes but by carefully analyzing each resource request to see if it could be safely granted. The question arises: is there an algorithm that can always avoid deadlock by making the right choice all the time? The answer is a qualified yes-we can avoid deadlocks, but only if certain information is available in advance. A scheduling algorithm that can avoid deadlocks is due to Dijkstra (1965) and is known as the banker's algorithm.

This algorithm can be applied to the general case of an arbitrary number of processes and an arbitrary number of resource classes. Figure 8 shows how it works.

Fig. 8

In Fig. 8 we see two matrices. The one on the left shows how many of each resource is currently assigned to each of the five processes. The matrix on the right shows how many resources each process still needs in order to complete. As in the single resource case, processes must state their total resource needs before executing, so that the system can compute the right-hand matrix at each step. The three vectors at the right of the figure show the existing resources, E, the possessed resources, P, and the available resources, A, respectively. From E we see that the system has six tape drives, three plotters, four printers, and two CDROMs. Of these, five tape drives, three plotters, two printers, and two CD-ROMs are currently assigned. This fact can be seen by adding up the four resource columns in the left-hand matrix. The available resource vector is simply the difference between what the system has and what is currently in use. The algorithm for checking to see if a state is safe can now be stated.

1. Look for a row, R, whose unmet resource needs are all smaller than or equal to A. If no such row exists, the system will eventually deadlock since no process can run to completion.

2. Assume the process of the row chosen requests all the resources it needs (which is guaranteed to be possible) and finishes. Mark that process as terminated and add all its resources to the A vector. (process A and vector A, process E and vector E are different entity).

3. Repeat steps 1 and 2 until either all processes are marked terminated, in which case the initial state was safe, or until a deadlock occurs, in which case it was not.

If several processes are eligible to be chosen in step 1, it does not matter which one is selected: the resource pool either gets larger, or at worst, stays the same. For the Fig.8, vector A satisfies need of the process D first who runs and releases all its resources.=> after D finishes

Vectors P= (4,2,2,1) and A=(2,1,2,1)

=> Now either row A or E can be selected. Suppose process A is selected and it finishes

P=(1,2,1,0) and A=(5,1,3,2)

=> vector A can satisfy need of remaining processes (i.e.B,C,E) which can be selected in any order.So the current state of the system is safe as all processes are marked terminated. The above check is made after each resource granted to process. Suppose that process B now acquires a printer. This granting modifies Fig.8 tables as below(Fig.9):

Fig.9Applying algorithm again, we find that state of the system is safe as all processes can be marked terminated.3.4 Deadlock Prevention

If we can ensure that at least one of the four conditions for deadlock is never satisfied, then deadlocks will be impossible(Havender, 1968).

First let us attack the mutual exclusion condition. If no resource were ever assigned exclusively to a single process, we would never have deadlocks. However, this leads to race condition as resource is accessed by multiple processes. This may lead to chaos and unexpected functioning of software.

The second of the conditions stated by Coffman looks more promising. If we can prevent processes that hold resources from waiting for more resources, we can eliminate deadlocks. One way to achieve this goal is to require all processes to request all their resources before starting execution. If everything were available, the process would be allocated whatever it needed and could run to completion. If one or more resources were busy, nothing would beallocated and the process would just wait. An immediate problem with this approach is that many processes do not know how many resources they will need until they have started running. Another problem is that resources will not be used optimally with this approach.

.

Attacking the third condition (no preemption) is even less promising than attacking the second one. If resources are taken away forcibly (preemptive resources) from processes that deadlock could be prevented as processes do no have to wait. But all resources can not be made preemptive as it may lead to chaos.

The circular wait can be eliminated in several ways. One way is simply to have a rule saying that a process is entitled only to a single resource at any moment. If it needs a second one, it must release the first one. Another way to avoid the circular wait is to provide a global numbering of all the resources, as shown in Fig. 3-10(a). Now the rule is this: processes can request resources whenever they want to, but all requests must be made in numerical order. A process may request first a printer and then a tape drive, but it may not request first a plotter and then a printer. With this rule, the resource allocation graph can never have cycles.

Fig.10

Let us see why this is true for the case of two processes, in Fig. 3-10(b). We can get a deadlock only if A requests resource j and B requests resource i. Assuming i and j are distinct resources, they will have different numbers. If i > j, then A is not allowed to request j. If i < j, then B is not allowed to request i. Either way, deadlock is impossible.