Exercise 6.45 Greg Hudson ------------- To see how long the chain of executions is, let's define a(i) to be the length of the chain executions (not counting the first execution) needed to establish that two executions have equivalent results if a single process's input is changed at the beginning of round i, where by "input is changed at the beginning of round i", we mean that the initial value of a process is changed if i = 0, or that a message which was received at round i in one execution was not received in the other, if i > 0. a(f) is 1+2(n-f) as follows: in our proof, to establish that two executions are identical if the input of one process (call it j) is changed at round f, we first assume that f-1 other processes have halted previously. Then we turn off the messages from j to the other n-f processes one by one until they are all off (n-f executions). Then we change the input of process j at round f (one execution). Finally, we turn the messages from j to the other n-f processes back on one by one again until process j didn't fail at all (n-f executions). This takes a total of 1+2(n-f) executions. a(i) for i 2 test-flag(2)[1] flag(2) --> 0 try[2] set-flag-1[2] flag(2) <-- 1 test-turn[2] turn --> 2 set-turn[1] turn <-- 2 set-flag-2[1] flag(1) <-- 2 set-flag-2[2] flag(2) <-- 2 and both processes proceed to go to the critical region, violating the mutual exclusion property. The key here is that process 2 does set-flag-1 and test-turn between process 1's test-flag(2) and set-turn. The second stage of DjikstraME resolves this kind of race condition by having whichever process sets its flag to 2 last fail the check stage (the other process might fail as well, but at least one of the processes has grabbed turn and will succeed the next time around). Exercise 10.4 Greg Hudson ------------- Assertion 10.3.5: In any reachable system state, if pc[i] is in {check, leave-try, crit, reset}, then flag(i) = 2. This is proved by induction on the length of an execution. Since each pc[i] is try at the beginning of the execution, we have the basis case. Assume that assertion 10.3.5 holds at the beginning of a transition; then the only transitions which might violate the condition are set-flag-2[i], check(j)[i], crit[i], and exit[i] (all other transitions leave the antecedent false). set-flag-2[i] satisfies the consequent of the condition by setting flag(i) to 2. check(j)[i] and crit[i] have the consequent of the condition true at the beginning of the transition by the induction assumption. For exit[i] you need the implicit assumption that exit[i] is only reached from crit[i] through transitions which don't set flag(i) (that is, through code which is isn't our state variables). (If you were to literally follow the code on page 258, you could instead prove by a very simple induction that exit[i] is never reached at all.) At any rate, none of the transitions will violate the condition and thus assertion 10.3.5 holds.