thread synchronization
play

Thread Synchronization: the presence of bugs Foundations not their - PowerPoint PPT Presentation

Edsger s perspective Testing can only prove Thread Synchronization: the presence of bugs Foundations not their absence! Properties Safety properties Nothing bad happens Property: a predicate that is evaluated over a run of the


  1. Edsger’ s perspective Testing can only prove Thread Synchronization: the presence of bugs… Foundations …not their absence! Properties Safety properties “Nothing bad happens” Property: a predicate that is evaluated over a run of the program (a trace) No more than processes are simultaneously k in the critical section “every message that is received was Messages that are delivered are delivered in previously sent” FIFO order No patient is ever given the wrong medication Not everything you may want to say about a Windows never crashes program is a property: “the program sends an average of 50 A safety property is “prefix closed”: messages in a run” if it holds in a run, it holds in its every prefix

  2. Liveness properties A really cool theorem “Something good eventually happens” A process that wishes to enter the critical section eventually does so Every property is a combination of a safety Some message is eventually delivered property and a liveness property Medications are eventually distributed to patients Windows eventually boots (Alpern & Schneider) Every run can be extended to satisfy a liveness property if it does not hold in a prefix of a run, it does not mean it may not hold eventually Critical Section Critical Section A segment of code involved in reading and writing a shared data area Mutual Exclusion: At most threads are k concurrently in the critical section (Safety) Used profusely in an OS to protect data structures (e.g., queues, shared variables, lists, …) Key assumptions: Finite Progress Axiom: Processes execute at a finite, positive, but otherwise unknown, speed. Processes can halt only outside of the critical section (by failing, or just terminating) wait-free synchronization (Herlihy, 1991)

  3. Critical Section Critical Section Mutual Exclusion: At most threads are Mutual Exclusion: At most threads are k k concurrently in the critical section (Safety) concurrently in the critical section (Safety) Access Opportunity: A thread that wants to Access Opportunity: A thread that wants to enter the critical section will eventually succeed enter the critical section will eventually succeed (Liveness) (Liveness) Bounded waiting: If a thread is in its entry i section, then there is a bound on the number of times that other threads are allowed to enter i the critical section before ’ s request is granted i (Safety) Critical Section: General Program Structure Too Much Milk Entry section OO programming style “Lock” before Associate a lock with entering critical each shared object section Methods that access Wait if already locked shared objects are critical section Critical Section code Acquire/release locks when entering/ exiting Exit section a method that defines “Unlock” when leaving a critical section the critical section

  4. Formalizing Too Much Milk! “Too Much Milk” Jack Jill Shared variables Look in the fridge: “Look in the fridge for milk” - check out of milk variable “milk” Leave for store Look in fridge: no milk “Put milk away” - increment “milk” Arrive at store Leave for store Safety Buy milk Arrive at store Arrive at home: Buy milk At most one person buys milk put milk away Arrive at home: put Liveness milk away If milk is needed, eventually somebody Oh no! buys milk Solution #0: Solution #0: Taking Turns Taking Turns Jack Jill Jack Jill procedure Check-Milk procedure Check-Milk procedure Check-Milk procedure Check-Milk while(turn ≠ Jack) relax; while(turn ≠ Jill) relax; while(turn ≠ Jack) relax; while(turn ≠ Jill) relax; while (Milk) relax; while (Milk) relax; while (Milk) relax; while (Milk) relax; buy milk; buy milk; buy milk; buy milk; turn := Jill turn := Jack turn := Jill turn := Jack Safe? Why? True, False Live? Why? True, False Bounded waiting? True, false

  5. Solution #1: Solution #0: Taking Turns Leave a note procedure Check-Milk procedure Check-Milk procedure Check-Milk Leave note = lock while(turn ≠ Jack) relax; while(turn ≠ Jill) relax; if (noMilk) { while (Milk) relax; while (Milk) relax; Remove note = unlock if (noNote) { buy milk; buy milk; leave Note; turn := Jill turn := Jack buy milk; If you find a note remove Note from your roommate- } Safe? Yes! } don’ t buy! it is either Jack’ s or Jill turn Live? No Safe? Live? Bounded waiting? Why? what if the other guy stops checking milk? Bounded waiting? Yes ... and the bound is 1! Solution #1: Solution #1: Leave a note Leave a note procedure Check-Milk Leave note = lock Jack/Jill If you find a note from your if (noMilk) { Remove note = unlock if (noNote) { roommate don’ t buy! if (noMilk) { leave Note; if (noNote) { buy milk; Leave note ≈ lock If you find a note leave Note; remove Note buy milk; from your roommate- Remove note ≈ unlock } remove Note } don’ t buy! } } Safe? Live? Bounded waiting? Why?

  6. Solution #1: Solution #1: Leave a note Leave a note Jack/Jill Jack/Jill If you find a note from your If you find a note from roommate don’ t buy! your roommate don’ t buy! if (milk==0) { if (milk == 0) { if (!note) { if (note==0) { Leave note ≈ lock Leave note ≈ lock note = True; note = 1; milk++; milk++; Remove note ≈ unlock Remove note ≈ unlock note = False; note = 0; } } Safe? Safe? } } This “solution” makes the problem worse! T1 T1 T2 S S i f (milk==0) { w i f (milk==0) { w sometime it works, sometime it doesn’ t i if (!note) { if (!note) { i note = True; t note = True; Oh no! t milk++; milk++; c c note = False; note = False; h } h } } } What if we leave Solution #2: Colored Notes the note first? Jack Jill Leave Blue note Leave Pink note if (noPinknote) { if (noBluenote) { if (noMilk) { Leave note; if (noMilk) { if (noMilk) { buy milk; buy milk; if (noNote) { if (noNote) { } } leave Note; if (noMilk) { } } Remove Blue note Remove Pink note buy milk; buy milk; remove Note remove Note } } } }

  7. Solution #2: Colored Notes Solution #2: Colored Notes Jack Jill Jack Jill BlueNote = 1; PinkNote = 1; BlueNote = 1; PinkNote = 1; A 1 if (PinkNote == 0) { if (BlueNote == 0) { B 1 A 1 if (PinkNote == 0) { if (BlueNote == 0) { B 1 A 2 if (milk == 0) { if (milk == 0) { B 2 A 2 if (milk == 0) { if (milk == 0) { B 2 A 3 milk++; milk++; B 3 A 3 milk++; milk++; B 3 } } } } B 4 } } } } B 5 BlueNote = 0; PinkNote = 0; BlueNote = 0; PinkNote = 0; Proof of Safety Proof of Liveness Case 2: PinkNote == 0, milk > 0 By contradiction: Not Live! Impossible. milk > 0 is a stable property, so Suppose Jack and Jill both buy milk Jack would fail test A 2 and never buy milk Consider state of variables (PinkNote,milk) at A 1 Case 3: PinkNote == 0, milk == 0 Case 1: PinkNote == 1 Impossible. Jill cannot be executing in B 1 -B 3 (PinkNote is not 1!) Impossible, since Jack ends up buying milk Since (BlueNote==1 or milk>0) is stable, then Jill will not pass B 1 Too Much Milk: Solution #3 Lessons Jill Jack PinkNote = 1; BlueNote = 1; if (BlueNote == 0) { Last solution works, but it is really while (PinkNote == 1) { if (milk == 0) { ; unsatisfactory: milk++; } } Complicated; proving correctness is tricky A 1 if (milk == 0) { } milk++; even for the simple example PinkNote = 0; } Inefficient: while thread is waiting, it is } consuming CPU time BlueNote = 0; Asymmetric: hard to scale to many threads Proof of Liveness Proof of Safety Incorrect(?) : instruction reordering can Jill will eventually set PinkNote = 0 Similar to previous case produce surprising results (no loops) Jack will then reach line A 1 if Jack finds milk, done If still no milk, Jack will buy it

  8. Solution #3.1 (Peterson’ s): Towards a solution combine ideas from #0 & #2 We introduce two variables: The problem then boils down to establishing the following: : id of thread allowed to enter CS under contention turn i : thread is executing in CS, or trying to do so in i T i in i ∧ ( ¬ in j ∨ ( in j ∧ turn = i )) = in i ∧ ( ¬ in j ∨ turn = i ) How do we How can we do that? prove it? Claim: If the following invariant holds when T i enters the critical section, so does mutual exclusion entry i : in i := true while ( in j ∧ turn ̸ = i ) ( ( in j ∧ turn = i ) ) ∧ ¬ in j in i ∨ does not desire wants to enter wants to enter CS in j in i in j to enter CS CS, but it is ’ s turn in i A first fix A dirty trick To establish the invariant, we add an auxiliary variable that tracks the position of the PC Add assignment to to establish second disjunct α turn Thread T 0 Thread T 1 Thread T 0 Thread T 1 while(!terminate) while(!terminate) { while(!terminate) while(!terminate) { { { in 0 := true in 1 := true in 1 := true in 0 := true { in 0 } { in 1 } { in 0 } { in 1 } turn = 1 turn = 0 α 0 α 1 while while ( in 1 ^ turn 6 = 0); ( in 0 ^ turn 6 = 1) turn = 1 turn = 0 { in 0 ∧ ( ¬ in 1 ∨ turn = 0) } { in 0 ∧ ( ¬ in 1 ∨ turn = 0 ∨ at ( α 1 )) } { in 1 ∧ ( ¬ in 0 ∨ turn = 1) } { in 1 ∧ ( ¬ in 0 ∨ turn = 1 ∨ at ( α 0 )) } while while ( in 1 ^ turn 6 = 0); ( in 0 ^ turn 6 = 1); CS 0 CS 1 { in 0 ∧ ( ¬ in 1 ∨ turn = 0) } { in 1 ∧ ( ¬ in 0 ∨ turn = 1) } . . . . . . in 0 = false in 1 = false CS 0 CS 1 NCS 0 NCS 1 } } . . . but these . . . in 0 = false in 1 = false invariants NCS 0 NCS 1 do not hold! } }

Recommend


More recommend