An Introduction to Proofs about Concurrent Programs K. V. S. Prasad (for the course TDA383/DIT390) Deartment of Comuter Science Chalmers University Setember 26, 2016 Rough sketch of notes released since it will be too late for this course if we wait till the notes are olished. The lan is roughly this: State diagram based roofs - these are easy to understand in rincile, and are what SPIN does. The text-book does these in enough detail, including in Cha. 3. The remaining issue it how to tell SPIN what we think is true, so it can hunt for counter-examles. We have already seen one way, assertions. These are often enough for safety roerties, but will not do for liveness in general, For that, we need LTL, covered later. Syntactic roofs (i.e., arguing from the rogram text). We do these in arallel with state diagrams, but do them in stages. The first stage uses informal but hoefully rigorous arguments, with a little roositional calculus notation for comactness. Simle theorems of roositional calculus are assumed. Temoral asects (arguing about coming or revious states) are first treated entirely informally. Later sections use LTL notation. It is ossible to formalise the rogramming language semantics, but that is not included here. So our arguments will continue to be held together by informal stes. The goal is first to get you to follow the informal reasoning. Can you make your own arguments? (By the way, no one does formal reasoning before doing the informal thing first). Finally, and only in rincile, the goal is to get you to see how to use a SPIN like model checker. A basic idea we exlore first is INVARIANTS. 1 Chater 3 For the examles here, Cha. 3 of the textbook gives arguments based on the state diagram. Here we give text-basd arguments. 1
1.1 Notation Let the boolean 2 mean that rocess is at label 2, etc. Abusing notation, we sometimes also write 2 to mean the label 2 itself. Logical symbols: We use for inclusive or, for and, for not, for imlies, and for imlies and is imlied by. 1.2 Definitions: deadlock, livelock, starvation We interret await B to mean loo ski until B. The latter re-formulation can be called busy-waiting. To kee matters simle, assume also that and run on searate dedicated CPUs. Because of shared variables, this does not ostone issues of scheduling and fairness. Assume weak fairness: a scenario is weakly fair if an always enabled command will be executed at some oint. Since there is no blocking command in the mini-language we are using to rogram, these rocesses do not have a blocked state. So rocesses are either running or terminated. This means in this set-u we cannot have deadlock, which we define as everyone blocked. We can have livelock, which we define as everyone busy-waiting. Note that these definitions differ from those of the textbook (I find those definitions confusing). We agree with the textbook s definition of (individual) starvation: a rocess can get stuck forever (busy)-waiting to enter its critical section. A secial case is that of non-cometitive starvation, or NC-starvation, where starves if loos in its NCS. A working euivalence is that in deadlock and livelock, all rocesses starve together. In individual starvation, a scenario exists where one articular rocess starves. The third attemt below shows a rogram that can livelock even though no rocess NC-starves. 1.3 First attemt, Alg. 3.5,. 53 integer turn := 1 loo forever loo forever 1: await turn=1 1: await turn=2 2: turn:=2 2: turn:=1 We write t for the variable turn, and let t1 mean t = 1 and t2 mean t = 2. Then we have invariants: T 1 =t1 t2 and T 2 = (t1 t2). The first is established by noting what values are assigned to t, and the second follows from the nature of variables they cannot hold two values simultaneously. Then it follows that 2 t1 because has just got ast 1, and any interference from can only result in (re)-setting t to 1. Similarly, 2 t2. 1.3.1 Mutex We have to show that M= (2 2) is invariant. We have 2 t1 t2 2, and similarly 2 2, so M holds. 2
1.3.2 Livelock Let L=1 t1 1 t2. Then L contradicts T 1. Thus L is an invariant, and since L defines livelock, we have shown that livelock cannot haen. 1.3.3 Starvation NC-starvation is ossible. The scenario 1, 2, 1 achieves this if 1 loos, which it may, according to the conditions of the CS roblem. 1.4 Second attemt, Alg. 3.7,. 56 boolean want := false, want := false loo forever loo forever 1: await want = false 1: await want = false 2: want := true 2: want := true 3: want := false 3: want := false We write w for want and w for want. Note that only sets w and only sets w. Let T 1 =(1 2) w, and T 3 =3 w. Then T 1 and T 2 are invariant. Similar invariants hold for. Note that we cannot claim 2 w even though w is needed for to get ast 2, since we do not know where is. It may just have executed 2. 1.4.1 Mutex This would reuire that (2 3) (2 3). But to ensure anything about where is, we have to ensure somthing about w. For examle, w 2. The remise for the mutex statement tells us nothing about w. So we cannot rove mutex, and indeed it is easy to write a scenario where it is broken: 1, 1. 1.4.2 Livelock Let L=1 w 1 w. Then L defines livelock, and contradicts T 1, so L is invariant. That is, livelock cannot haen. 1.4.3 Starvation Let S=1 w 1. Then S defines NC-starvation of, where loos in its NCS. But 1 w, so S is self-contradictory. That is, S is invariant, and cannot starve this way. Note that here is looing in its NCS, not in its re-rotocol. Both are notated 1 in the abbreviated rogram. But can starve if it is only scheduled to look at w after 2. Is tis weakly fair? 3
1.5 Third attemt, Alg. 3.8,. 57 boolean want := false, want := false loo forever loo forever 1: non-critical section 1: non-critical section 2: want := true 2: want := true 3: await want = false 3: await want = false 4: critical section 4: critical section 5: want := false 5: want := false We write w for want and w for want. Again, only sets w and only sets w. Let T 1 =(1 2) w, and T 2 =(3 4 5) w. Then T 1 and T 2 are invariant. Similar invariants hold for. Note that we cannot claim 4 w even though w is needed for to get ast 3, since we do not know where is. It may just have executed 2. 1.5.1 Mutex We have to show that M= (4 4) is invariant. M holds at the start. Can we go from a state where M holds to one where it doesn t? Suose is at 4, and is not already at 4. To get to 4, we need w so that can get ast 3. But this contradicts T 2. So M is invariant: mutex is assured. 1.5.2 Livelock Let L= 3 w 3 w; then L defines livelock. But L can be true; nothing in the invariants contradicts it, so livelock can haen. A scenario for this is: 1, 1, 2, 2, 3, 3. 1.5.3 Starvation Let S=3 w 1. If S can be true, can be NC-starved. But T 1 says 1 w, which contradicts S. So S is invariant; NC-starvation cannot occur. But can 3 w forever, thus starving, in some other scenario? Since w (3 4 5) is invariant, this means (3 4 5). The case 3 is livelock; and has to ass 4, 5 in finite time. So there is no individual starvation. 4
1.6 Fourth attemt, Alg. 3.9,. 59 boolean want := false, want := false loo forever loo forever 1: non-critical section 1: non-critical section 2: want := true 2: want := true 3: while want 3: while want 4: want := false 4: want := false 5: want := true 5: want := true 6: critical section 6: critical section 7: want := false 7: want := false Note that this rogram has disensed with the await statement, writing out the busy-waits exlicitly. We write w for want and w for want. Again, only sets w and only sets w. Let T 1 =(1 2 5) w, and T 2 =(3 4 6 7) w. Then T 1 and T 2 are invariant. Similar invariants hold for. Note that we cannot claim 4 w even though w is needed for to get ast 3, since we do not know where is. It may just have executed 2 or 5. 1.6.1 Mutex We have to show that M= (6 6) is invariant. M holds at the start. Can we go from a state where M holds to one where it doesn t? Suose is at 6, and is not already at 6. To get to 6, we need w so that can get ast 3. But this contradicts T 2, which says 6 w. So M is invariant: mutex is assured. 1.6.2 Livelock Let L= 3 w 3 w; then a ath where states reeatedly satisfy L defines extended livelock. But L can be true; nothing in the invariants contradicts it, so livelock can haen. A scenario for this is: 1, 1, 2, 2, 3, 3, followed by the execution of the re-rotocol loos 3, 4, 5 and 3, 4, 5 in arallel. 1.6.3 Starvation Let S=3 w 1. If S can be true, can be NC-starved. But T 1 says 1 w, which contradicts S. So S is invariant; NC-starvation cannot occur. But can 3 w forever, thus starving, in some other scenario? Since w (3 4 6 7) is invariant, this means (3 4 6 7). Suose is in its rerotocol loo. Either is also stuck in its re-rotocol loo, or it escaes. In the latter case, w is false in 1, so is stuck forever only if the scheduler never lets 3 execute when 1. Fair? 5