Mutual Exclusion en Semaforen Werkcollege Processen Wouter Geraedts w.geraedts@student.ru.nl 24 mei 2013 Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 1 / 18
Outline Hyman s Algoritme Hyman s Algoritme Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 2 / 18
Hyman s Algoritme 1 // initially turn =0, blocked [0]= blocked [1]= false 2 void Protocol ( int id) { 3 while ( true ) { 4 blocked [id] = true ; 5 while ( turn!= id) { 6 while ( blocked [1 - id ]) { 7 /* do nothing */ 8 }; 9 turn = id; 10 }; 11 CriticalSection ; 12 blocked [id] = false ; 13 } 14 } Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 3 / 18
Hyman s Algoritme Opgave 1 Maak een Uppaal model van Hyman s algoritme en gebruik Uppaal om aan te tonen dat het algoritme niet voldoet aan mutual exclusion. Leg uit wat er fout gaat. Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 4 / 18
Imperatieve (pseudo)code UPPAAL If-else 1 pre ; 2 if(c) { 3 s_t ; 4 } else { 5 s_f ; 6 } 7 post ; pre c s_t post!c s_f Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 5 / 18
Imperatieve (pseudo)code UPPAAL While 1 pre ; 2 while (c) { 3 s; 4 } 5 post ; s c!c pre post Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 6 / 18
Hyman s Algoritme als UPPAAL-model!blocked[1-id] CS turn = id turn == id turn!= id blocked[1-id] blocked[id] = false initial blocked[id] = true Declarations System declarations 1 typedef int [0,1] id_t ; 2 3 bool blocked [ id_t ]; 4 id_t turn ; 1 system Process ; Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 7 / 18
Output van UPPAAL Hyman s Algoritme UPPAAL Verifier A[]!(Process(0).CS && Process(1).CS) Tegenvoorbeeld: 1 P1 start, moet wachten want turn!= 0 2 P1 stopt vlak voor turn = id; 3 P0 gaat door naar CS, want turn == 0 4 P1 executeert turn = 1; 5 P1 gaat door naar CS, want turn == 1 Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 8 / 18
Hyman s Algoritme 1 // initially turn =0, blocked [0]= blocked [1]= false 2 void Protocol ( int id) { 3 while ( true ) { 4 blocked [id] = true ; 5 while ( turn!= id) { 6 while ( blocked [1 - id ]) { 7 /* do nothing */ 8 }; 9 turn = id; 10 }; 11 CriticalSection ; 12 blocked [id] = false ; 13 } 14 } Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 9 / 18
Hyman s Algoritme Opgave 2 Indien processen altijd de kritieke sectie na eindige tijd verlaten, dan zal ieder proces dat bij regel 2 van de code arriveert uiteindelijk in de kritieke sectie komen. Toon aan dat Hyman s algoritme niet aan deze voorwaarde voldoet. Ook wel: wordt starvation uitgesloten? Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 10 / 18
Wordt starvation uitgesloten? Nee, hier een voorbeeld-trace: 1 P0 gaat door naar CS 2 P1 moet wachten, zit vast in blocked-loop 3 P0 is klaar, blocked[id] = false; 4 P0 begint opnieuw, blocked[id] = true; 5 P1 krijgt weer de beurt, maar blijft vast zitten in blocked-loop Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 11 / 18
Implementatie van semaforen met binaire semaforen 1 void semwait ( semaphore s) { 2 semwaitb ( mutex ); 3 s - -; 4 if(s < 0) { 5 semsignalb ( mutex ); 6 semwaitb ( delay ); 7 } 8 else semsignalb ( mutex ); 9 } 10 void semsignal ( semaphore s) { 11 semwaitb ( mutex ); 12 s ++; 13 if(s <= 0) 14 semsignalb ( delay ); 15 semsignalb ( mutex ); 16 } Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 12 / 18
Opdracht 5.16 Hyman s Algoritme There is a flaw in the preceding program. Demonstrate the flaw and propose a change that will fix it. Hints: Two threads call semwait(s), but their execution stops before calling semwaitb(delay). All that you need to do is move a single line of the program. Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 13 / 18
Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 14 / 18
Fix implementatie van semaforen met binaire semaforen 1 void semwait ( semaphore s) { 2 semwaitb ( mutex ); 3 s - -; 4 if(s < 0) { 5 semsignalb ( mutex ); 6 semwaitb ( delay ); 7 } 8 semsignalb ( mutex ); // else weggehaald 9 } 10 void semsignal ( semaphore s) { 11 semwaitb ( mutex ); 12 s ++; 13 if(s <= 0) 14 semsignalb ( delay ); 15 else semsignalb ( mutex ); // else toegevoegd 16 } Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 15 / 18
Een foute oplossing van het Jurassic Park-probleem Grade it for correctness. Ignore syntax and missing variable declarations. 1 resource Jurassic_Park () 2 sem car_avail := 0, car_taken := 0, car_filled := 0, passenger_released := 0 3 process passenger (i := 1 to num_passengers ) 4 do true -> 5 nap (int ( random (1000* wander_time ))) 6 P( car_avail ); V( car_taken ); P( car_filled ) 7 P( passenger_released ) 8 od 9 end passenger 10 process car (j := 1 to num_cars ) 11 do true -> 12 V( car_avail ); P( car_taken ); V( car_filled ) 13 nap (int ( random (1000* ride_time ))) 14 V( passenger_released ) 15 od 16 end car 17 end Jurassic_Park Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 16 / 18
Een foute oplossing van het Jurassic Park-probleem Grade it for correctness. Ignore syntax and missing variable declarations. 1 resource Jurassic_Park () 2 sem car_avail := 0, car_taken := 0, car_filled := 0, passenger_released := 0 3 process passenger (i := 1 to num_passengers ) 4 do true -> 5 nap (int ( random (1000* wander_time ))) 6 P( car_avail ); V( car_taken ); P( car_filled ) 7 P(passenger released) 8 od 9 end passenger 10 process car (j := 1 to num_cars ) 11 do true -> 12 V( car_avail ); P( car_taken ); V( car_filled ) 13 nap (int ( random (1000* ride_time ))) 14 V(passenger released) 15 od 16 end car 17 end Jurassic_Park Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 17 / 18
Een goede oplossing van het Jurassic Park-probleem 1 resource Jurassic_Park2 () { 2 typedef int [ num_cars ] car_t ; 3 sem embarkation = 1, car_avail = 0, car_taken = 0; 4 sem car_done [ num_cars ]; 5 car_t car_embarkation ; 6 7 process passenger () { 8 car_t car_mine ; 9 while ( true ) { 10 passenger_idle (); // Wandel door de veilige zone 11 P( car_avail ); // Wacht tot er een auto klaar staat 12 car_mine = car_embarkation ; 13 V( car_taken ); // Stap in de auto, doe de deur dicht 14 P( car_done [ car_mine ]); // Stap uit de auto 15 } 16 } 17 process car ( car_t j) { 18 while ( true ) { 19 P( embarkation ); // Claim opstapplaats als voorste auto in rij 20 car_embarkation = j; 21 V( car_avail ); // Open de deuren van de auto 22 P( car_taken ); // Wacht tot iemand in de auto stapt 23 V( embarkation ); // Geef opstapplaats vrij 24 car_work (); // Rijd door de gevaren - zone 25 V( car_done [j]); // Open de deuren van de auto 26 } 27 } 28 } Wouter Geraedts 24 mei 2013 Werkcollege Processen 2013-05-24 18 / 18