720 likes | 901 Views
Mutual exclusion. read/write variables. The Bakery Algorithm. The algorithm is similar with the read-modify-write algorithm. There is a queue: The process in the head is in critical section A new process is inserted in the tail. Algorithm outline.
E N D
Mutual exclusion read/write variables
The Bakery Algorithm The algorithm is similar with the read-modify-write algorithm There is a queue: The process in the head is in critical section A new process is inserted in the tail
Algorithm outline t = tail; tail = tail + 1; Wait until t == head; Entry: Critical section Exit: head = head + 1; (tail and head are shared variables, t is a local variable)
Problem: this part of the code doesn’t behave correctly //read tail t = tail; tail = tail + 1; Entry: //write tail
A good scenario 0 tail
A good scenario (t=0) 0 Read 0 Write 1 1 tail
A good scenario (t=1) 1 0 Read 1 Write 2 2 tail
A good scenario (t=2) 1 2 0 Read 2 Write 3 3 tail
A bad scenario 0 Read 0 0 tail
A bad scenario 0 0 Read 0 Write 1 Write 1 (delayed) 1 tail
A bad scenario 0 1 0 Write 1 (delayed) Read 1 Write 2 2 tail
A bad scenario 0 1 0 Read 2 Write 3 Write 1 (delayed) 2 3 tail
A bad scenario 0 1 0 Write 1 Read 2 Write 3 2 1 Wrong value!!! tail
A Solution: distributed counting V[1]=0 V[2]=0 V[3]=0 V[4]=0 0 0 0 0 We need an array of shared variables v[1], v[2], …, v[n] Process has value v[i]
V[1]=0 V[2]=0 V[3]=0 V[4]=0 0 0 0 0 In the entry code, a process reads the values of all other processes. The new value is the maximum + 1
V[1]=0 V[2]=1 V[3]=0 V[4]=0 0 1 0 0 entry Max = 0; Max + 1 = 1;
V[1]=0 V[2]=1 V[3]=0 V[4]=2 0 1 0 2 entry entry Max = 1; Max + 1 = 2;
V[1]=0 V[2]=1 V[3]=3 V[4]=2 0 1 3 2 entry entry entry Max = 2; Max + 1 = 3;
V[1]=4 V[2]=1 V[3]=3 V[4]=2 4 1 3 2 entry entry entry entry Max = 3; Max + 1 = 4; Everybody gets a unique value (a unique position in the distributed queue)
V[1]=4 V[2]=1 V[3]=3 V[4]=2 4 1 3 2 entry entry entry entry Then the processes compare their values with all the other values. The lowest value enters the critical region (different than 0)
V[1]=4 V[2]=1 V[3]=3 V[4]=2 4 1 3 2 critical region entry entry entry reads all values Realizes it has the lowest value
V[1]=4 V[2]=0 V[3]=3 V[4]=2 0 4 3 2 entry entry entry exit sets value to 0
V[1]=4 V[2]=0 V[3]=3 V[4]=2 4 0 3 2 critical region entry entry
V[1]=4 V[2]=0 V[3]=3 V[4]=0 4 0 3 0 entry entry exit
V[1]=4 V[2]=0 V[3]=3 V[4]=0 4 0 3 0 entry critical region And so on……
A problem: When two processes enter at the same time, they may choose the same value. V[1]=0 V[2]=0 V[3]=0 V[4]=0 0 0 0 0 entry entry
The maximum values they read are the same V[1]=0 V[2]=1 V[3]=0 V[4]=1 0 1 0 1 entry entry
Solution: use ID’s to break symmetries (lowest ID wins) V[1]=0 V[2]=1 V[3]=0 V[4]=1 1, 4 0 0 1, 2 critical section entry
V[1]=0 V[2]=0 V[3]=0 V[4]=1 0 1, 4 0 0 exit entry
The Complete Bakery Algorithm Process i: V[i] = 0; choosing[i] = false; Entry: choosing[i] = true; V[i] = max(V[1], V[2], …, V[n])+1; choosing[i] = false; for (k = 1; k <= n; k++) Wait until choosing[k] == false; Wait until V[k] == 0 or (V[k],k) > (V[i],i) Critical section Exit: V[i] = 0;
Advantages of the bakery algorithm: • Uses Read/Write variables • Satisfies no lockout property Disadvantages: • Uses n shared variables for n processes (actually, we cannot do better than that) • The values can grow unbounded (we would like to find an algorithm with bounded values)
Mutual Exclusion for 2 processes high priority process low priority process Entry: Want[0] = 1; Wait until want[1]== 0; Critical section Want[0] = 0; 1: Want[1] = 0; Wait until want[0] ==0; Want[1] = 1; if (want[0] == 1) goto 1; Critical section Want[1] = 0; Exit: Good: Uses only bounded values on variables Problem: low priority process may lockout
An equal priority algorithm Process 0 Process 1 Entry: 1: Want[0] = 0; Wait until (want[1]== 0 or Priority == 0); Want[0] = 1; if priority == 1 then if Want[1] == 1 then goto Line 1 Else wait until Want[1]==0; Critical section Priority = 1; Want[0] = 0; 1: Want[1] = 0; Wait until (want[0]== 0 or Priority == 1); Want[1] = 1; if priority == 0 then if Want[0] == 1 then goto Line 1 Else wait until Want[0]==0; Critical section Priority = 0; Want[1] = 0; Exit: Good: Uses only bounded values on variables Supports no lockout
The Tournament Algorithm We can implement a tournament mutual exclusion algorithm, using the equal priority pairwise algorithm
Critical section winner
Advantages of tournament algorithm • O(n) variables • Bounded values of variables • Preserves no lockout • (since each pair mutual exclusion • is no lockout)
MCS Mutual Exclusion Algorithm head tail Lock=0 Lock=1 Lock=0 Lock=0 next next next next nil T Process in critical region Process waiting to get in critical region
Local memories (for example cache) head tail Lock=0 Lock=1 Lock=0 Lock=0 next next next next nil Processes Spin on their own memories T Global Shared Memory
head tail Lock=0 Lock=1 Lock=0 Lock=0 next next next next nil Critical region T
head tail Lock=1 Lock=1 Lock=0 Lock=0 next next next next nil Critical region T
head tail Lock=1 Lock=1 Lock=0 next next next nil Critical region T
head tail Lock=1 Lock=1 next next nil T Critical region
nil T
Entry Code for processor i: Qi = pointer to a new queuenode; // Qi, *Qi is in local memory Qi->Lock = 0; Qi->Next = nil; Ti = Swap(T, Qi); //Ti is in local memory If Ti nil then Ti -> next = Qi; else Qi->Lock =1; //it is at the head of the queue Wait until Qi->lock = 1;
Atomic operation Swap(T,Qi) { x = T; //read T T = Qi; // swap T with Qi return x; // return old value of T }
Qi Empty queue nil Lock=0 next nil T Qi is created
Qi nil Lock=0 next nil Ti T After swap operation
Qi in critical section Lock=1 next nil T After if statement