CS-206 Concurrency Lecture 6 Peterson’s, Filter & Bakery Last to write victim[L] Spring 2015 Prof. Babak Falsafi parsa.epfl.ch/courses/cs206/ ncs Assumed to enter L-1 A B n-L+1 = 4 n-L+1 = 4 cs By way of contradiction all enter L Adapted from slides originally developed by Maurice Herlihy and Nir Shavit from the Art of Multiprocessor Programming, and Babak Falsafi EPFL Copyright 2015 EPFL CS-206 – Spring 2015 Lec.6 - 1 Where are We? M T Lecture & Lab W 16-Feb 17-Feb 18-Feb 19-Feb 20-Feb 23-Feb 24-Feb 25-Feb 26-Feb 27-Feb 2-Mar 3-Mar 4-Mar 5-Mar 9-Mar 10-Mar 11-Mar 12-Mar 13-Mar 16-Mar 17-Mar 18-Mar 19-Mar 20-Mar 23-Mar 24-Mar 25-Mar 26-Mar 27-Mar 30-Mar 31-Mar 1-Apr 2-Apr 3-Apr 6-Apr 7-Apr 8-Apr 9-Apr 10-Apr 13-Apr 14-Apr 15-Apr 16-Apr 17-Apr 20-Apr 21-Apr 22-Apr 23-Apr 24-Apr 27-Apr 28-Apr 29-Apr 30-Apr 1-May 4-May 5-May 6-May 7-May 8-May 11-May 12-May 13-May 14-May 15-May 18-May 19-May 20-May 21-May 22-May 25-May 26-May 27-May 28-May 29-May EPFL CS-206 – Spring 2015 T F 6-Mar u Peterson’s algorithm w Two threads w Deadlock free w Starvation free u From 2 to n threads w Filter lock w Lamport’s Bakery algo u Next week w Synchronization Lec.6 - 2 Recall: LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { … flag[i] = true; while (flag[j]) {} } EPFL CS-206 – Spring 2015 Lec.6 - 3 LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { … flag[i] = true; while (flag[j]) {} Set my flag } EPFL CS-206 – Spring 2015 Lec.6 - 4 LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { … flag[i] = true; while (flag[j]) {} } Wait for other flag to become false EPFL CS-206 – Spring 2015 Lec.6 - 5 Recall: LockTwo public class LockTwo implements Lock { private int victim; public void lock() { int i = ThreadID.get(); victim = i; while (victim == i) {}; } public void unlock() {} } EPFL CS-206 – Spring 2015 Lec.6 - 6 LockTwo public class LockTwo impleints Lock { private int victim; public void lock() { Let other … victim = i; while (victim == i) {}; } go first public void unlock() {} } EPFL CS-206 – Spring 2015 Lec.6 - 7 LockTwo public class LockTwo impleints Lock { private int victim; Wait for public void lock() { … permission victim = i; while (victim == i) {}; } public void unlock() {} } EPFL CS-206 – Spring 2015 Lec.6 - 8 LockTwo public class LockTwo impleints Lock { private int victim; public void lock() { … Nothing victim = i; while (victim == i) {}; } to do public void unlock() {} } EPFL CS-206 – Spring 2015 Lec.6 - 9 LockOne & LockTwo u LockOne w Guarantees mutual exclusion w Using while(flag[]) w But might deadlock while entering u LockTwo w Guarantees waiting until another thread wants to enter w Using while (victim == i) w But might deadlock if one thread finishes w Other might continue waiting EPFL CS-206 – Spring 2015 Lec.6 - 10 Peterson’s Algorithm (Gary L. Peterson) public void lock() { … flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } EPFL CS-206 – Spring 2015 Lec.6 - 11 Peterson’s Algorithm Announce I’m public void lock() { interested … flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 12EPFL CS-206 – Spring 2015 Lec.6 - 12 Peterson’s Algorithm Announce I’m public void lock() { interested … flag[i] = true; Defer to other victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } EPFL CS-206 – Spring 2015 Lec.6 - 13 Peterson’s Algorithm Announce I’m public void lock() { interested … flag[i] = true; Defer to other victim = i; while (flag[j] && victim == i) {}; } public void unlock() { Wait while other flag[i] = false; interested & I’m } the victim EPFL CS-206 – Spring 2015 Lec.6 - 14 Peterson’s Algorithm Announce I’m interested public void lock() { … flag[i] = true; Defer to other victim = i; while (flag[j] && victim == i) {}; } public void unlock() { Wait while other flag[i] = false; interested & I’m } No longer interested EPFL CS-206 – Spring 2015 the victim Lec.6 - 15 Mutual Exclusion (1) writeB(Flag[B]=true)èwriteB(victim=B) public void lock() { … flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } From the Code EPFL CS-206 – Spring 2015 Lec.6 - 16 Also from the Code (2) writeA(victim=A)èreadA(flag[B]) èreadA(victim) public void lock() { … flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } EPFL CS-206 – Spring 2015 Lec.6 - 17 Assumption (3) writeB(victim=B)èwriteA(victim=A) W.L.O.G. assume A is the last thread to write victim EPFL CS-206 – Spring 2015 Lec.6 - 18 Combining Observations (1) writeB(flag[B]=true)èwriteB(victim=B) (3) writeB(victim=B)èwriteA(victim=A) (2) writeA(victim=A)èreadA(flag[B]) è readA(victim) EPFL CS-206 – Spring 2015 Lec.6 - 19 Combining Observations (1) writeB(flag[B]=true)èwriteB(victim=B) (3) writeB(victim=B)èwriteA(victim=A) (2) writeA(victim=A)èreadA(flag[B]) è readA(victim) EPFL CS-206 – Spring 2015 Lec.6 - 20 Combining Observations (1) writeB(flag[B]=true)èwriteB(victim=B) (3) writeB(victim=B)èwriteA(victim=A) (2) writeA(victim=A)èreadA(flag[B]) è readA(victim) A read flag[B] == true and victim == A, so it could not have entered the CS (QED) EPFL CS-206 – Spring 2015 Lec.6 - 21 Deadlock Free public void lock() { … while (flag[j] && victim == i) {}; u Thread blocked w only at while loop w only if other’s flag is true w only if it is the victim u Solo: other’s flag is false u Both: one or the other not the victim EPFL CS-206 – Spring 2015 Lec.6 - 22 Starvation Free u Thread i flag[j] u But, would be blocked only if j re-enters so that == true and victim == i when j re-enters w it sets victim to j w So i gets in public void lock() { … flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } EPFL CS-206 – Spring 2015 Lec.6 - 23 The Filter Algorithm for n Threads There are n-1 “waiting rooms” called levels u At each level w At least one enters level w At least one blocked if many try u Only ncs one thread makes it through cs EPFL CS-206 – Spring 2015 Lec.6 - 24 Filter class Filter implements Lock { int[] level; // level[i] for thread i int[] victim; // victim[L] for level L } public Filter(int n) { 2 n-1 0 level = new int[n]; victim = new int[n]; level 0 0 4 0 0 0 0 0 for (int i = 1; i < n; i++) { 1 level[i] = 0; }} … 2 4 Thread 2 at level 4 EPFL CS-206 – Spring 2015 n-1 victim Lec.6 - 25 Filter class Filter implements Lock { … public void lock(){ for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i level[k] >= L) && victim[L] == i ) {}; }} public void unlock() { level[i] = 0; }} EPFL CS-206 – Spring 2015 Lec.6 - 26 Filter class Filter implements Lock { … public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} public void release(int i) { level[i] = 0; }} One level at a time EPFL CS-206 – Spring 2015 Lec.6 - 27 Filter class Filter implements Lock { … public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; // busy wait Announce }} public void release(int i) { intention to enter level[i] = 0; level L }} EPFL CS-206 – Spring 2015 Lec.6 - 28 Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} public void release(int i) { level[i] = 0; }} EPFL CS-206 – Spring 2015 Give priority to anyone but me Lec.6 - 29 Filter class Filter implements Lock { Wait long as someone else is at int as level[n]; int victim[n]; higher level, and I’m designated public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; same or victim while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} public void release(int i) { level[i] = 0; }} EPFL CS-206 – Spring 2015 Lec.6 - 30 Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} public void release(int i) { Thread enters level L when level[i] = 0; the loop }} EPFL CS-206 – Spring 2015 it completes Lec.6 - 31 Claim u Start at level L=0 u At most n-L threads enter level L u Mutual exclusion at level L=n-1 ncs L=0 L=1 L=n-2 cs L=n-1 EPFL CS-206 – Spring 2015 Lec.6 - 32 Induction Hypothesis • No more than n-(L-1) at level L-1 • Induction step: by contradiction all at level L-1 enter level L u A last to write victim[L] u B is any other thread at level L u Assume ncs assume L-1 has n-(L-1) L has n-L cs EPFL CS-206 – Spring 2015 prove Lec.6 - 33 Proof Structure ncs A B Assumed to enter L-1 n-L+1 = 4 Last to write victim[L] n-L+1 = 4 cs By way of contradiction all enter L Show that A must have seen B in level[L] and since victim[L] == A could not have entered EPFL CS-206 – Spring 2015 Lec.6 - 34 Just Like Peterson (1) writeB(level[B]=L)èwriteB(victim[L]=B) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} From the Code EPFL CS-206 – Spring 2015 Lec.6 - 35 From the Code (2) writeA(victim[L]=A)èreadA(level[B]) èreadA(victim[L]) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((∃ k != i) level[k] >= L) && victim[L] == i) {}; }} EPFL CS-206 – Spring 2015 Lec.6 - 36 By Assumption (3) writeB(victim[L]=B)èwriteA(victim[L]=A) By assumption, A is the last thread to write victim[L] EPFL CS-206 – Spring 2015 Lec.6 - 37 Combining Observations (1) writeB(level[B]=L)èwriteB(victim[L]=B) (3) writeB(victim[L]=B)èwriteA(victim[L]=A) (2) writeA(victim[L]=A)èreadA(level[B]) èreadA(victim[L]) EPFL CS-206 – Spring 2015 Lec.6 - 38 Combining Observations (1) writeB(level[B]=L)èwriteB(victim[L]=B) (3) writeB(victim[L]=B)èwriteA(victim[L]=A) (2) writeA(victim[L]=A)èreadA(level[B]) èreadA(victim[L]) EPFL CS-206 – Spring 2015 Lec.6 - 39 Combining Observations (1) writeB(level[B]=L)èwriteB(victim[L]=B) (3) writeB(victim[L]=B)èwriteA(victim[L]=A) (2) writeA(victim[L]=A)èreadA(level[B]) èreadA(victim[L]) A read level[B] ≥ L, and victim[L] = A, so it could not have entered level L! EPFL CS-206 – Spring 2015 Lec.6 - 40 No Starvation u Filter Lock satisfies properties: w Just like Peterson Alg at any level w So no one starves u But what about fairness? w Threads EPFL CS-206 – Spring 2015 can be overtaken by others Lec.6 - 41 Bounded Waiting u Want stronger fairness guarantees u Thread not “overtaken” too much u If A starts before B, then A enters before B? u But what does “start” mean? u Need to adjust definitions …. EPFL CS-206 – Spring 2015 Lec.6 - 42 Bounded Waiting u Divide lock() method into 2 parts: w Doorway interval: w Written DA w always finishes in finite steps w Waiting interval: w Written WA w may take unbounded steps EPFL CS-206 – Spring 2015 Lec.6 - 43 First-Come-First-Served u For threads A and B: DAk è DB j w A’s k-th doorway precedes B’s j-th doorway w Then CSAk è CSBj w A’s k-th critical section precedes B’s j-th critical section w B cannot overtake A w If EPFL CS-206 – Spring 2015 Lec.6 - 44 Fairness Again u Filter Lock satisfies properties: w No one starves w But very weak fairness w Can w That’s EPFL CS-206 – Spring 2015 be overtaken arbitrary # of times pretty lame… Lec.6 - 45 Bakery Algorithm u Provides First-Come-First-Served u How? w Take a “number” w Wait until lower numbers have been served u Lexicographic w (a,i) order > (b,j) w If a > b, or a = b and i > j EPFL CS-206 – Spring 2015 Leslie Lamport Lec.6 - 46 Bakery Algorithm class Bakery implements Lock { boolean[] flag; Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; } } … EPFL CS-206 – Spring 2015 Lec.6 - 47 Bakery Algorithm class Bakery implements Lock { boolean[] flag; Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = } } … EPFL CS-206 – Spring 2015 0 f f 6 2 t f f t f n-1 f 0 0 4 0 0 5 0 0 0; CS Lec.6 - 48 Bakery Algorithm class Bakery … public void flag[i] = label[i] = implements Lock { lock() { true; max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 49 Bakery Algorithm class Bakery … public void flag[i] = label[i] = implements Lock { Doorway lock() { true; max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 50 Bakery Algorithm class Bakery … public void flag[i] = label[i] = implements Lock { I’m interested lock() { true; max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 51 Bakery Algorithm class Bakery … public void flag[i] = label[i] = implements Lock { Take increasing label (read labels in some arbitrary order) lock() { true; max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 52 Bakery Algorithm class Bakery … public void flag[i] = label[i] = implements Lock { Someone is interested lock() { true; max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 53 Bakery Algorithm class Bakery implements Lock { boolean flag[n]; Someone int label[n]; is interested … public void lock() { flag[i] = true; label[i] = max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } … whose (label,i) in lexicographic order is lower EPFL CS-206 – Spring 2015 Lec.6 - 54 Bakery Algorithm class Bakery implements Lock { … public void unlock() { flag[i] = false; } } EPFL CS-206 – Spring 2015 Lec.6 - 55 Bakery Algorithm class Bakery implements Lock { … No longer interested public void unlock() { flag[i] = false; } } labels are always increasing EPFL CS-206 – Spring 2015 Lec.6 - 56 No Deadlock u There is always one thread with earliest label u Ties are impossible (why?) EPFL CS-206 – Spring 2015 Lec.6 - 57 First-Come-First-Served u If class Bakery implements Lock { DA è DB then w A’s label is smaller u And: w writeA(label[A]) è w readB(label[A]) è w writeB(label[B]) è u So public void lock() { flag[i] = true; label[i] = max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } readB(flag[A]) B sees w smaller label for A w locked out while flag[A] is true EPFL CS-206 – Spring 2015 Lec.6 - 58 Mutual Exclusion u Suppose A and B in CS together u Suppose A has earlier label u When B entered, it must have seen w flag[A] is false, or w label[A] > label[B] class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0], …,label[n-1])+1; while (∃k flag[k] && (label[i],i) > (label[k],k)); } EPFL CS-206 – Spring 2015 Lec.6 - 59 Mutual Exclusion u Labels are strictly increasing so u B must have seen flag[A] == false EPFL CS-206 – Spring 2015 Lec.6 - 60 Mutual Exclusion u Labels are strictly increasing so u B must have seen flag[A] == false u LabelingB è readB(flag[A]) è writeA(flag[A]) è LabelingA EPFL CS-206 – Spring 2015 Lec.6 - 61 Mutual Exclusion u Labels are strictly increasing so u B must have seen flag[A] == false u LabelingB è readB(flag[A]) è writeA(flag[A]) è LabelingA u Which contradicts the assumption that A has an earlier label EPFL CS-206 – Spring 2015 Lec.6 - 62 Summary u LockOne gives us mutual exclusion u LockTwo gives us starvation freedom w as long as both threads are running u Peterson’s u Filter combines the two for 2 threads lock w n-thread solution (with n=L levels) w Mutual exclusion at L=n-1 u Lamport’s w Get Bakery a ticket w Order EPFL CS-206 – Spring 2015 tickets with thread ID’s lexographically Lec.6 - 63
© Copyright 2024