Concurrency Problem Synchronization: oo Much Milk Order of thread execution is non-determistic Multiprocessg v A system may conta multiple processors Ë cooperatg threads/processes can execute simultaneously Multi-programmg v /process execution can be terleaved because of timeslicg Operations are often not atomic Example: x x + is not atomic! Goal: Ensure that your concurrent program works under ALL possible terleavg 2 he Fundamental Issue Critical Sections In all these cases, what we thought to be an atomic operation is not done atomically by the mache Defition: An atomic operation is one that executes to completion without any terruption or failure An atomic operation has an all or nothg flavor: Either it executes to completion, or it did not execute at all, and it executes without terruptions Atomic no no one one can can see see a partially-executed state!! Key Key challenge: how how to to implement atomic semantics? A critical section is an abstraction that consists of a number of consecutive program structions all code with the section executes atomically Critical sections are used profusely an OS to protect data structures (e.g., queues, shared variables, lists, ) A critical section implementation must be: correct: for a given k, only k thread can execute the critical section at any given time (usually, k ) efficient: gettg to and out of critical section must be fast concurrency control: a good implementation allows maximum concurrency preservg correctness flexible: a good implementation must have as few restrictions as practically possible 3 4
5 Safety and Liveness A really cool theorem Safety property : nothg bad happens holds every fite execution prefix v Wdows never crashes v if one general attacks, both do v a program never termates with a wrong answer Liveness property: somethg good eventually happens no partial execution is irremediable v Wdows always reboots v both generals eventually attack v a program eventually termates Every property is a combation of a safety property and a liveness property (Alpern and Schneider) 6 Nice, but what s your pot? Critical Section: Implementation Safety: At most k threads are concurrently the critical section Liveness: A thread that wants to enter the critical section, will eventually succeed Anythg else? Bounded waitg: If a thread i is entry section, then there is a bound on the number of times that other threads are allowed to enter the critical section before thread i s request is granted Is Is bounded waitg a safety or or a liveness property? 7 Basic idea: Restrict programmg model Permit access to shared variables only with a critical section General program structure Entry section v Lock before enterg critical section v Wait if already locked v Key pot: synchronization may volve wait Critical section code Exit section v Unlock when leavg the critical section Object-oriented programmg style Associate a lock with each shared object Methods that access shared object are critical sections Acquire/release locks when enterg/exitg a method that defes a critical section extbook shows shows non-oo non-oo examples; much much easier easier to to thk thk OO OO 8
9 Coordation: Reality V! oo much milk! Jack Look the fridge; out of milk Leave for store Arrive at store Buy milk Arrive home; put milk away Jill Look fridge; out of milk Leave for store Arrive at store Buy milk Arrive home; put milk away Oh, no! Fridge and and milk milk are are shared data data structures Formalizg oo Much Milk Shared variables Look the fridge for milk check a variable Put milk away update a variable Safety property At most one person buys milk Liveness Someone buys milk when needed How can we solve this problem? 0 oo Much Milk: Solution #0 oo Much Milk: Solution # ( Jack); Jack); // // relax relax (Milk); (Milk);// // relax relax : : Jill Jill ( Jill); Jill); // // relax relax (Milk); (Milk);// // relax relax : : Jack Jack If If (nomilk) (nomilk) // // check check milk milk if if (nonote) (nonote) // // check check if if roommate roommate is is gettg gettg milk milk leave leave Note; Note; remove remove Note; Note; Will this solution work? Safe? Yes! Must have to buy milk! Live? What if the other guy never comes around to check the milk Bounded waitg? Sure, and the bound is! Introduce the concept of a note vleave a note lock vremove note unlock vdon t buy if note wait Will this solution work? Safe? No! s can get context switched after checkg whether there is a note, but before leavg a note Live? Yes! A note left will be eventually removed Bounded waitg? his solution is worse than before!! It works sometime and doesn t some other times What if we switch the order of checks? 2
3 oo Much Milk: Solution #2 Solution #3 (a.k.a. Peterson s algorithm): combe ideas of 0 and 2 Jack Jack Leave Leave Blue Blue note note If If (nonote (nonote Pk) Pk) if if (nomilk) (nomilk) Remove Remove Blue Blue note note Jill Jill Leave Leave Pk Pk note note If If (nonote (nonote Blue) Blue) if if (nomilk) (nomilk) Remove Remove Pk Pk note note Variables: i : : thread i is executg, or attemptg to execute, id of thread allowed to enter if multiple want to Claim: We can achieve mutual exclusion if the followg variant holds before enterg the critical section: Safe? Live? What happens if note has no color? j ( j Ÿ i)) Ÿ i i false ( 0 ( 0 Ÿ )) Ÿ ) Ÿ ( ( Ÿ 0)) Ÿ 0 ) fi (( 0) Ÿ ( )) false 4 owards a solution We hit a snag he problem boils down to establishg the followg right after entry i j ( j Ÿ i)) Ÿ i j i) Ÿ i How can we do that? entry i i : ( j Ÿ i); 0 (!termate) 0 : true 0 ( Ÿ 0) 0 (!termate) : true ( 0 Ÿ ); Ÿ 0 ) he assignment to 0 validates the variant! 5 6
7 What can we do? Safe? Add assignment to to establish the second disjunct 0 0 (!termate) (!termate) (!termate) (!termate) a 0 : 0 : : : 0 a : : ; ; : : 0 0 ( ( Ÿ Ÿ ( ( ); ); 0 0 at(a at(a ) ))) Ÿ 0 0 at(a at(a 0 ) 0 ))) 0 0 0 : 0 : : : N N 0 N 0 N 0 0 (!termate) (!termate) (!termate) (!termate) a 0 : 0 : : : 0 a : : ; ; : : 0 0 ( ( Ÿ Ÿ ( ( 0 0 ); ); at(a at(a ) ) ) ) Ÿ Ÿ 0 0 at(a at(a 0 ) 0 ) ) ) 0 0 0 : 0 : : : N N 0 N N 0 If both, then at(a ) 0) Ÿ Ÿ 0 at(a 0 ) ) Ÿ Ÿ at(a 0 ) Ÿ at(a ) ( 0) Ÿ ( ) false 8 Live? Bounded waitg? 0 0 (!termate) (!termate) (!termate) (!termate) S S : : ( ( 0) 0) R R : : ( ( 0) 0) 0 : 0 : : : a S S 2 : 2 : 0 ( ( 0) 0) a R R 2 : 2 : ( ( 0) 0) : : ; ; : : S S 2 2 R R 2 2 ( ( Ÿ Ÿ ( ( ); ); S S 3 : 3 : at(a ) ) 0) 0) R R 3 : 3 : Ÿ Ÿ 0 0 at(a 0 ) 0 ) ) ) 0 0 S S 3 3 R R 3 3 0 : 0 : : : S S R R N N 0 0 N N Non-blockg: 0 before N 0, stuck at loop S Ÿ R 2 Ÿ ( 0) Ÿ ( 0) false Deadlock-free: and 0 at, before enterg the critical section S 2 Ÿ R 2 Ÿ ( ( 0)) Ÿ ( Ÿ ( )) fi ( 0) Ÿ ( ) false 9 0 0 (!termate) (!termate) 0 : 0 : : : ; ; ( ( Ÿ Ÿ 0 0 0 : 0 : N N 0 0 Yup! 0 0 (!termate) (!termate) : : : : ( ( ); ); 0 0 : : N N 0 0 20
2 oo Much Milk: Lessons Last solution works, but it is really unsatisfactory Solution is complicated; provg correctness is tricky even for the simple example While thread is waitg, it is consumg CPU time How can we do better? Defe higher-level programmg abstractions to simplify concurrent programmg Use hardware features to elimate busy waitg Stay tuned