deadlockans
Short Description
Download deadlockans...
Description
EECS 678 Introduction to Operating Systems Homework 2 Answer Key (Total of 200 Points)
Question 1 (Chap 6; 20 Points)
Consider the following set of processes P1 and P2: P1: { shared int x;
P2:{ shared int x;
x = 7; while (1) { x--; x++; if (x != 7) { printf(``x is %d'',x) } } }
x = 7; while (1) { x--; x++; if (x != 7) { printf(``x is %d'',x) } } }
N ote ote
that the scheduler in a uniprocessor u niprocessor system system would implement pseudo-parallel execution of these two concurrent processes by interleaving their instructions, without restriction on the order of the interl eaving.
1.
S how how
an execution (i.e., trace the sequence of inter-leavings of statements) such that the statement x is 7 is printed. 2. S how how how the statement x is 9 is printed. You should remember that the increments/decrements increments/decrements at the source language level are not n ot done atomically, i.e., the assembly assembly language l anguage code: 3.
4. 5. . 6 . 7 8.
LD INCR STO
R0,X R0 R0,X
/* load R0 from memory location x */ /* increment R0 */ /* store the incremented value back in X */
9.
implements implements the single C increment i nstruction ( x++ x++ ). Answer:
For an output of x is 7, the interleaving producing the required behavior is f airly eas y to f ind since it requires only an interleaving at the source languag e statement level. T he essential f act here is that the test for the value of x is interleaved with the increment of x by the other process. Thus, x was not equal to 7 when the test was performed, but was equal to 7 by the time the value of x was read from memory for pr inting. P1: P1: P2: P1: P2: P1:
x--; x++; x--; if (x != 7) x++; printf("x is %d", x);
M(x) 6 7 6 6 7 7
"x is 7" is printed .
For x is 9 we need to be more inventive, since we need to us e inter-leavings of the machine instructions to f ind a way for the value of x to be established as 8 so it can then be evaluated as 9 in a later cycle. N otice that the machine instructions are divided into block s at places w here a context switch between P1 and P2 ha ppens. Note also, that these context switches ha ppen at machine instruction boundar ies, but not always as s ource line boundar ies. In other words, if you examine them clos ely you should be able to see that the context switches interleave portions of source language statements in each process's execut ion. Instruction P1: LD R0, x P2: LD R0, x P2: DECR R0 P2: STO R0, x
M(x) 7 7 7 6
P1-R0 7
P2-R0 --
7 7 7
7 6 6
P1: P1: P1: P1: P1: P1:
DECR STO LD INCR STO if(x
R0 6 R0, x 6 R0, x 6 R0 6 R0, x 7 != 7) printf("x is %d", x );
6 6 6 7 7
6 6 6 6 6
P2: P2: P2: P2: P2:
LD R0, x 7 INCR R0 7 STO R0, x 8 if(x != 7) printf("x is %d", x ); "x is 8" is printed .
7 7 7
7 8 8
P1: P1: P1: P1:
LD DECR STO LD
R0, x R0 R0, x R0, x
8 8 7 7
8 7 7 7
8 8 8 8
P2: LD R0, x P2: DECR R0 P2: STO R0, x
7 7 6
7 7 7
7 6 7
8 8
6 6
P1: INCR R0 6 P1: STO R0, x 8 P1: if(x != 7) printf("x is %d", x );
P1: "x is 8" is printed . P2: P2: P2: P2: P2:
LD R0, x 8 INCR R0 8 9 STO R0, x if(x != 7) printf("x is %d", x ); "x is 9" is printed .
8 8 8
8 9 9
Question 2 (Chap 6; 15 Points) I n
the previous problem, concurrent access to a shared variable was done without protecting it as a critical section. Consider what portion of the code in each process should be defined as a critical section, and show where/how to add semaphores to the program in the previous problem to control concurrency in a reasonable way. Done correctly, this will ensure that the printf() is never executed. Your solution should allow as much concurrency as possible, which means that the critical section should be as small as possible - but no smaller. N ote: treat the notion as much as possible reasonably and don't obsess over optimality too much. remember that it is always better to make sure it is correct, if less efficient than it might be, as opposed to striving for too much concurrency and straying onto an incorrect part of the design space. Answer:
Here the solution is si mple: enclose the oper ations on the shared var iable within sema phore oper ations which will ensure that only one process wi ll oper ate on x at a time. The only tr ick here is to realize that surrounding the statements th at decrement and increment x is not enough. W e have to enclose the if statement as well since it tests the value of x. If we do not, erroneous pr inting can still ha ppen if one process is in the middle of incrementing and decrement ingx, while another is testing x at theif. s: semaphore; P1: { shared int x; P(s); x = 7; V(s); for (;;) { P(s); x--; x++; if (x != 7) printf("x is %d", x); V(s); } } P2: { shared int x; P(s); x = 7; V(s);
for (;;) { P(s); x--; x++; if (x != 7) printf("x is %d", x); V(s); } }
Question 3 (Chap 6; 15 Points) E xplain
why spinlocks are not appropriate for uniprocessor systems, yet may be suitable for multiprocessor systems. Answer:
s pin lock is a busy-waiting a pproach to concurrency control. T hat means that when a process enter s a s pin-lock impleme ntation of the P oper ation, and the desired sema phore is already held, i t will sit in a loop continuously look ing to s ee if the sema phore has b ecome free. T he waiting process is thus fully CPU bound by the useless activity of running, or s pinning and thus the name, through the loop. T he is anexcellent a pproach to the pro blem, if all other concurre nt comput at ions in the system using the sema phore are k nown to use it for a short ti me, an d will thus s hortly free it. S pin-lock s are thus anexcellent a pproach to lock ing man y shared data structures in multi-processor sys tems b ecause they are held for a short time by processes that will also not be interrupted. Any process block ing on such a lock is thus assured to wait for only a short per iod, since the process holding the lock is executing on another CPU and will be releasing the lock in a short time. A classic error in multi processor systems is for a process to block while holding a s pin-lock , w hich can have dr astic effects on system performance. A
The crucial assumption for S pin-lock s is thus that the threa d of control holding the lock is actively execut ing concurrently with the threa d of control block ing on the lock . Sadly, in a uni processor system only one thread of control can be active at a time, because there is only one CPU, and the concurrency is gener ally ps eudo-concurrency for that reason. DMA by network , disk , or other device controller s theoretically introduces physical concurrency, but that is not relevant here. Thus, in a uni processor system, i f a thread of control uses a S pin-lock , and begins s pinning on it because the lock is already held, the lock mus t be held by a process that is not executing. S pinning on the lock is thus a huge waste of time because the process s pins through the loop continuously look ing at a sema phore var iable that cannot change valueuntil the s pinning process gives up the CPU and permit s the process holding the lock to execute again, thus giving it a chance to f inish using the lock and to releas e it. At the logical extreme, the system is now deadlocked because the s pinning process is CPU- bound, and will never give the process holding the lock a chance to run and thus releas e it. In reality, the CPU-time quantum of the s pinning process wi ll eventually expire, an d pr ior ity aging will reduce its pr ior ity, so the process holding the lock will eventually run, so the system will not be permanently frozen, but a huge num ber of CPU cycles will certainly b e wasted. T his is why a sleepwakeup implementation for P and V is much more a ppropr iate in uni-processor s.
Question 4 (Chap 6; 15 Points) S how
that if the wait and signal operations are not executed atomically, then mutual exclusion may be violated. Answer:
Pseudo-code, or an algor ithmic descr i ption, of the wait and signal oper ations are def ined as follows (S ection 6.5, 7th Edition): int S=1; wait(S) { while (S
View more...
Comments