Mutual Exclusion
description
Transcript of Mutual Exclusion
Mutual Exclusion
Companion slides forThe Art of Multiprocessor Programming
by Maurice Herlihy & Nir Shavit
Modified by Pavol Černý, Programming Paradigms for
Concurrency, Fall 2010, IST Austria
Review: Peterson’s Algorithm
flag[0]
← 0
no access
flag[0] ←0
flag[1] = 0 or
turn = 0
access
request
flag[0] ← 1
turn ← 1 flag[0]
← 0
no access
flag[1] ←0
access
request
flag[1] ← 1
turn ← 0
Alice Bob
flag[0] = 0 or
turn = 1
Art of Multiprocessor Programming
3
Implementing a Counter
public class Counter { private long value;
public long getAndIncrement() { temp = value; value = temp + 1; return temp; }}
Make these steps indivisible using
locks
Use Peterson’s
Art of Multiprocessor Programming
4
Locks (Mutual Exclusion)
public interface Lock {
public void lock();
public void unlock();}
Art of Multiprocessor Programming
5
Locks (Mutual Exclusion)
public interface Lock {
public void lock();
public void unlock();}
acquire lock
Art of Multiprocessor Programming
6
Locks (Mutual Exclusion)
public interface Lock {
public void lock();
public void unlock();}
release lock
acquire lock
Art of Multiprocessor Programming
7
Using Locks
public class Counter { private long value; private Lock lock; public long getAndIncrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }}
Art of Multiprocessor Programming
8
Using Locks
public class Counter { private long value; private Lock lock; public long getAndIncrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }}
acquire Lock
Art of Multiprocessor Programming
9
Using Locks
public class Counter { private long value; private Lock lock; public long getAndIncrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }}
Release lock(no matter what)
Art of Multiprocessor Programming
10
Using Locks
public class Counter { private long value; private Lock lock; public long getAndIncrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }}
Critical section
Peterson’s in Javapublic void lock() { flag[i] = 1; turn = 1-i; while (!((flag[1-i] == 0) || (turn == i))) { }}
public void unlock() { flag[i] = 0;}
flag[0]
← 0
no access
flag[0] ←0
flag[1] = 0 or
turn = 0
access
request
flag[0] ← 1
turn ← 1
Questions from last lecture:
1.Can we make do with two shared bits (instead of three)?2.How can one extend this idea to n processes?3.Does the algorithm work in Java?
Run it and see. What is the problem?
Where is the fault in our proof?
Review: Peterson’s Algorithm
Question 1: Modify Peterson’s to use two bits
public void lock() { if (i==0) { flag[0] = 1;
while (!(flag[1] == 0)) { } } else {
while (!( flag[1] == 1)) {; flag[1] = 1;
while (!(flag[0] == 0)) { flag[1] = 0; }}
}}
public void unlock() { flag[i] = 0;}
Question 2: Modify Peterson’s for n processes
Today’s class
Question 3: But does it work in Java?
java Peterson … (results in deadlock)java Peterson ... (mutual exclusion fails
(if a counter is protected with these locks, we observe a problem after enough iterations))
public void lock() { flag[i] = 1; turn = 1-i; while (!((flag[1-i] == 0) || (turn == i))) { }}
public void unlock() { flag[i]=0;}
Art of Multiprocessor Programming
16
Fact
• Most hardware architectures don’t support sequential consistency
• Because they think it’s too strong
Art of Multiprocessor Programming
17
The Flag Example
time
x.write(1) y.read(0)
y.write(1) x.read(0)
time
Art of Multiprocessor Programming
18
The Flag Example
time
x.write(1) y.read(0)
y.write(1) x.read(0)
• Each thread’s view is sequentially consistent– It went first
Art of Multiprocessor Programming
19
The Flag Example
time
x.write(1) y.read(0)
y.write(1) x.read(0)
• Entire history isn’t sequentially consistent– Can’t both go first
Art of Multiprocessor Programming
20
The Flag Example
time
x.write(1) y.read(0)
y.write(1) x.read(0)
• Is this behavior really so wrong?– We can argue either way …
Art of Multiprocessor Programming
21
Opinion1: It’s Wrong
• This pattern– Write mine, read yours
• Is exactly the flag principle– Beloved of Alice and Bob– Heart of mutual exclusion
• Peterson• Bakery, etc.
• It’s non-negotiable!
Art of Multiprocessor Programming
22
Opinion2: But It Feels So Right …
• Many hardware architects think that sequential consistency is too strong
• Too expensive to implement in modern hardware
• OK if flag principle– violated by default– Honored by explicit request
Art of Multiprocessor Programming
23
Who knew you wanted to synchronize?
• Writing to memory = mailing a letter
• Vast majority of reads & writes– Not for synchronization– No need to idle waiting for post office
• If you want to synchronize– Announce it explicitly– Pay for it only when you need it
Art of Multiprocessor Programming
24
Explicit Synchronization
• Memory barrier instruction– Flush unwritten caches– Bring caches up to date
• Expensive
Art of Multiprocessor Programming
25
Volatile• In Java, can ask compiler to keep a
variable up-to-date with volatile keyword
• Also inhibits reordering & other “optimizations”
• Example:public static volatile int[] flag;
public static volatile int z = 0;
Art of Multiprocessor Programming
26
Mutual Exclusion
• Problem definitions• Solutions for 2 threads• Solutions for n threads• Fair solutions• Inherent costs
Art of Multiprocessor Programming
27
Warning
• You will never use these protocols• Understanding these is necessary
– The same issues show up everywhere– Except hidden and more complex
Art of Multiprocessor Programming 28
Formalizing the Problem
• Two types of formal properties in asynchronous computation:
• Safety Properties– Nothing bad happens ever– E.g. Mutual exclusion, No overtaking
• Liveness Properties – Something good happens eventually– E.g. Deadlock freedom, Starvation freedom
Art of Multiprocessor Programming
29
time
• An event a0 of thread A is– Instantaneous– No simultaneous events (break ties)
a0
Events
Art of Multiprocessor Programming
30
time
• A thread A is (formally) a sequence a0, a1, ... of events – “Trace” model
– Notation: a0 a1 indicates order
a0
Threads
a1 a2 …
Art of Multiprocessor Programming
31
• Assign to shared variable• Assign to local variable• Invoke method• Return from method• Lots of other things …
Example Thread Events
Art of Multiprocessor Programming
32
Threads are State Machines
Events are transitions
a0
a1a2
a3
Art of Multiprocessor Programming
33
States
• Thread State– Program counter– Local variables
• System state– Object fields (shared variables)– Union of thread states
Art of Multiprocessor Programming
34
time
• Thread A
Concurrency
Art of Multiprocessor Programming
35
time
time
• Thread A
• Thread B
Concurrency
Art of Multiprocessor Programming
36
time
Interleavings
• Events of two or more threads– Interleaved– Not necessarily independent (why?)
Art of Multiprocessor Programming
37
time
• An interval A0 =(a0,a1) is
– Time between events a0 and a1
a0 a1
Intervals
A0
Art of Multiprocessor Programming
38
time
Intervals may Overlap
a0 a1A0
b0 b1B0
Art of Multiprocessor Programming
39
time
Intervals may be Disjoint
a0 a1A0
b0 b1B0
Art of Multiprocessor Programming
40
time
Precedence
a0 a1A0
b0 b1B0
Interval A0 precedes interval B0
Art of Multiprocessor Programming
41
Precedence
• Notation: A0 B0
• Formally,– End event of A0 before start event of B0
– Also called “happens before” or “precedes”
Art of Multiprocessor Programming
42
Precedence Ordering
• Never true that A A
• If A B then not true that B A
• If A B & B C then A C
• Funny thing: A B & B A might both be false!
Art of Multiprocessor Programming
43
Partial Orders(review)
• Irreflexive:– Never true that A A
• Antisymmetric:– If A B then not true that B A
• Transitive:– If A B & B C then A C
Art of Multiprocessor Programming
44
Total Orders(review)
• Also– Irreflexive– Antisymmetric– Transitive
• Except that for every distinct A, B,– Either A B or B A
Art of Multiprocessor Programming
45
Repeated Events
while (mumble) { a0; a1;}
a0k
k-th occurrence of event a0
A0k
k-th occurrence of interval A0 =(a0,a1)
Art of Multiprocessor Programming
46
Mutual Exclusion
• Let CSik be thread i’s k-th critical
section execution
Art of Multiprocessor Programming
47
Mutual Exclusion
• Let CSik be thread i’s k-th critical
section execution
• And CSjm be thread j’s m-th critical
section execution
Art of Multiprocessor Programming
48
Mutual Exclusion
• Let CSik be thread i’s k-th critical
section execution
• And CSjm be j’s m-th execution
• Then either– or
Art of Multiprocessor Programming
49
Mutual Exclusion
• Let CSik be thread i’s k-th critical
section execution
• And CSjm be j’s m-th execution
• Then either– or
CSik CSj
m
Art of Multiprocessor Programming
50
Mutual Exclusion
• Let CSik be thread i’s k-th critical
section execution
• And CSjm be j’s m-th execution
• Then either– or
CSik CSj
m
CSjm CSi
k
Art of Multiprocessor Programming
51
Deadlock-Free• If some thread calls lock()
– And never returns– Then other threads must complete
lock() and unlock() calls infinitely often
– This is true for all fair schedules– Schedule is fair if all threads in CS or
concurrency parts proceed
• System as a whole makes progress– Even if individuals starve
Art of Multiprocessor Programming
52
Starvation-Free
• If some thread calls lock()– It will eventually return
• Individual threads make progress
Art of Multiprocessor Programming
53
Example – proving mutual exclusion
class LockOne implements Lock {private boolean[] flag = new boolean[2];public void lock() { flag[i] = true; while (flag[j]) {} }
Art of Multiprocessor Programming
54
LockOneclass LockOne implements Lock {private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} }
Set my flag
Art of Multiprocessor Programming
55
class LockOne implements Lock {private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} }
LockOne
Wait for other flag to go false
Set my flag
Art of Multiprocessor Programming
56
• Assume CSAj overlaps CSB
k
• Consider each thread's last (j-th and k-th) read and write in the lock() method before entering
• Derive a contradiction
LockOne Satisfies Mutual Exclusion
Art of Multiprocessor Programming
57
• writeA(flag[A]=true) readA(flag[B]==false) CSA
• writeB(flag[B]=true) readB(flag[A]==false) CSB
From the Code
class LockOne implements Lock {… public void lock() { flag[i] = true; while (flag[j]) {} }
Art of Multiprocessor Programming
58
• readA(flag[B]==false) writeB(flag[B]=true)
• readB(flag[A]==false) writeA(flag[A]=true)
From the Assumption
Art of Multiprocessor Programming
59
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
60
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
61
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
62
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
63
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
64
• Assumptions:– readA(flag[B]==false) writeB(flag[B]=true)
– readB(flag[A]==false) writeA(flag[A]=true)
• From the code– writeA(flag[A]=true) readA(flag[B]==false)
– writeB(flag[B]=true) readB(flag[A]==false)
Combining
Art of Multiprocessor Programming
65
Cycle!
Imposs
ible
in p
artial a
order
Art of Multiprocessor Programming
66
Deadlock Freedom
• LockOne Fails deadlock-freedom– Concurrent execution can deadlock
– Sequential executions OK
flag[i] = true; flag[j] = true; while (flag[j]){} while (flag[i]){}
Art of Multiprocessor Programming
67
The Filter Algorithm for n Threads
There are n-1 “waiting rooms” called levels
• At each level – At least one enters level– At least one blocked if many try
• Only one thread makes it through
ncs
cs
Art of Multiprocessor Programming
68
Filterclass Filter implements Lock { int[] level; // level[i] for thread i int[] victim; // victim[L] for level L
public Filter(int n) { level = new int[n]; victim = new int[n]; for (int i = 1; i < n; i++) { level[i] = 0; }}…
}
level
victim
n-1
n-1
0
1
0 0 0 0 0 04
2
2
Thread 2 at level 4
0
4
Art of Multiprocessor Programming
69
Filterclass 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; }}
Art of Multiprocessor Programming
70
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; }}
Filter
One level at a time
Art of Multiprocessor Programming
71
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 }} public void release(int i) { level[i] = 0; }}
Filter
Announce intention to enter level L
Art of Multiprocessor Programming
72
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; }}
Filter
Give priority to anyone but
me
Art of Multiprocessor Programming
73
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; }}
FilterWait as long as someone else is at
same or higher level, and I’m designated victim
Art of Multiprocessor Programming
74
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; }}
Filter
Thread enters level L when it completes the loop
Art of Multiprocessor Programming
75
Claim• Start at level L=0• At most n-L threads enter level L• Mutual exclusion at level L=n-1
ncs
cs L=n-1
L=1
L=n-2
L=0
Art of Multiprocessor Programming
76
Induction Hypothesis
• Assume all at level L-1 enter level L
• A last to write victim[L]
• B is any other thread at level L
• No more than n-L+1 at level L-1 or above • Induction step: by contradiction
ncs
cs
L-1 has n-L+1L has n-L
assume
prove
Art of Multiprocessor Programming
77
Proof Structurencs
cs
Assumed to enter L-1
By way of contradictionall enter L
n-L+1 = 4
n-L+1 = 4
A B
Last to writevictim[L]
A must have seen B in level[L] and since victim[L] == Acould not have entered
Art of Multiprocessor Programming
78
No Starvation
• Filter Lock satisfies properties:– Just like Peterson Alg at any level– So no one starves
• But what about fairness?– Threads can be overtaken by others
Art of Multiprocessor Programming
79
Bounded Waiting
• Want stronger fairness guarantees• Thread not “overtaken” too much• Need to adjust definitions ….
Art of Multiprocessor Programming
80
Bounded Waiting
• Divide lock() method into 2 parts:– Doorway interval:
• Written DA
• always finishes in finite steps
– Waiting interval:• Written WA
• may take unbounded steps
Art of Multiprocessor Programming
81
• For threads A and B:– If DA
k DB j
• A’s k-th doorway precedes B’s j-th doorway
– Then CSAk CSB
j
• A’s k-th critical section precedes B’s j-th critical section
• B cannot overtake A
First-Come First-Served
Break!
Art of Multiprocessor Programming
82
Art of Multiprocessor Programming
83
Bakery Algorithm
• Provides First-Come-First-Served• How?
– Take a “number”– Wait until lower numbers have been
served• Lexicographic order
– (a,i) > (b,j)• If a > b, or a = b and i > j
Art of Multiprocessor Programming
84
Bakery Algorithmclass 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; } } …
Art of Multiprocessor Programming
85
Bakery Algorithmclass 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; } } …
n-10
f f f f t ft
2
f
0 0 0 0 5 04 0
6
CS
Art of Multiprocessor Programming
86
Bakery Algorithm
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)); }
Art of Multiprocessor Programming
87
Bakery Algorithm
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)); }
Doorway
Art of Multiprocessor Programming
88
Bakery Algorithm
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)); }
I’m interested
Art of Multiprocessor Programming
89
Bakery Algorithm
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)); }
Take increasing label (read
labels in some arbitrary
order)
Art of Multiprocessor Programming
90
Bakery Algorithm
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)); }
Someone is interested
Art of Multiprocessor Programming
91
Bakery Algorithmclass Bakery implements Lock { boolean flag[n]; int label[n];
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));
}
Someone is interested
With lower (label,i) in
lexicographic order
Art of Multiprocessor Programming
92
Bakery Algorithm
class Bakery implements Lock { …
public void unlock() { flag[i] = false; }}
Art of Multiprocessor Programming
93
Bakery Algorithm
class Bakery implements Lock { …
public void unlock() { flag[i] = false; }}
No longer interested
labels are always increasing
Art of Multiprocessor Programming
94
No Deadlock
• There is always one thread with earliest label
• Ties are impossible (why?)
Art of Multiprocessor Programming
95
First-Come-First-Served
• If DA DBthen A’s label is smaller
• And:– writeA(label[A])
readB(label[A]) writeB(label[B]) readB(flag[A])
• So B is locked out while flag[A] is true
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));
}
Art of Multiprocessor Programming
96
Mutual Exclusion
• Suppose A and B in CS together
• Suppose A has earlier label
• When B entered, it must have seen– flag[A] is false, or– 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));
}
Art of Multiprocessor Programming
97
Mutual Exclusion
• Labels are strictly increasing so
• B must have seen flag[A] == false
Art of Multiprocessor Programming
98
Mutual Exclusion
• Labels are strictly increasing so
• B must have seen flag[A] == false
• LabelingB readB(flag[A]) writeA(flag[A]) LabelingA
Art of Multiprocessor Programming
99
Mutual Exclusion
• Labels are strictly increasing so
• B must have seen flag[A] == false
• LabelingB readB(flag[A]) writeA(flag[A]) LabelingA
• Which contradicts the assumption that A has an earlier label
Art of Multiprocessor Programming
100
Bakery Y232K Bugclass 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)); }
Art of Multiprocessor Programming
101
Bakery Y232K Bugclass 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)); }
Mutex breaks if label[i] overflows
Art of Multiprocessor Programming
102
Does Overflow Actually Matter?
• Yes– Y2K– 18 January 2038 (Unix time_t rollover)– 16-bit counters
• No– 64-bit counters
• Maybe– 32-bit counters
Art of Multiprocessor Programming
103
Is this Optimal Solution?
• The Bakery Algorithm is– Succinct,– Elegant, and– Fair.
• Q: So why isn’t it practical?• A: Well, you have to read N distinct
variables
Art of Multiprocessor Programming
104
Shared Memory
• Shared read/write memory locations called Registers (historical reasons)
• Come in different flavors– Multi-Reader-Single-Writer (Flag[])– Multi-Reader-Multi-Writer (Victim[])– Not that interesting: SRMW and SRSW
Art of Multiprocessor Programming
105
Theorem
At least N MRSW (multi-reader/single-writer) registers are needed to solve deadlock-free mutual exclusion.
N registers like Flag[]…
Art of Multiprocessor Programming
106
Proving Algorithmic Impossibility
CS
write
C
•To show no algorithm exists:• assume by way of contradiction one does, • show a bad execution that violates properties: • in our case assume an alg for deadlock free mutual exclusion using < N registers
Art of Multiprocessor Programming
107
Proof: Need N-MRSW RegistersEach thread must write to some register
…can’t tell whether A is in critical section
write
CS CS CS
write
A B C
Art of Multiprocessor Programming
108
Upper Bound
• Bakery algorithm– Uses 2N MRSW registers
• So the bound is (pretty) tight• But what if we use MRMW
registers?– Like victim[] ?
Art of Multiprocessor Programming
109
Bad News Theorem
At least N MRMW multi-reader/multi-writer registers are needed to solve deadlock-free mutual exclusion.
(So multiple writers don’t help)
Art of Multiprocessor Programming
110
Theorem (For 2Threads)
Theorem: Deadlock-free mutual exclusion for 2 threads requires at least 2 multi-reader multi-writer registers
Proof: assume one register suffices and derive a contradiction
Art of Multiprocessor Programming
111
Two Thread Execution
• Threads run, reading and writing R• Deadlock free so at least one gets in
BA
CS
Write(R)
CS
R
Art of Multiprocessor Programming
112
Covering State
Write(R)
B
A covering state for a Lock object is one in which there is at least one thread about to write to each shared location, but the object’s locations appear as if no thread is in the critical section or trying to enter the critical section.
Art of Multiprocessor Programming
113
Covering State for One Register Always Exists
Write(R)
B
In any protocol B has to write to the register before entering CS,
so stop it just before
Art of Multiprocessor Programming
114
Proof: Assume Cover of 1
A B
Write(R)
CS
A runs, possibly writes to the register, enters CS
Art of Multiprocessor Programming
115
Proof: Assume Cover of 1
A B
CS
B Runs, first obliterating any trace of A, then also enters the critical section
Write(R)
CS
Art of Multiprocessor Programming
116
Theorem
Deadlock-free mutual exclusion for 3 threads requires at least 3 multi-reader multi-writer registers
Art of Multiprocessor Programming
117
Proof: Assume Cover of 2
Write(RB)
B
Write(RC)
CA
Only 2 registers
Art of Multiprocessor Programming
118
Run A Solo
Write(RB)
B
Write(RC)
CA
Writes to one or both registers, enters CS CS
Art of Multiprocessor Programming
119
Obliterate Traces of A
Write(RB)
B
Write(RC)
CA
Other threads obliterate evidence that A entered CS CS
Art of Multiprocessor Programming
120
Mutual Exclusion Fails
Write(RB)
B
Write(RC)
CA
CS CS
CS looks empty, so another thread
gets in
Art of Multiprocessor Programming
121
Proof Strategy
• Proved: a contradiction starting from a covering state for 2 registers
• Claim: a covering state for 2 registers is reachable from any state where CS is empty
Art of Multiprocessor Programming
122
• If we run B through CS 3 times, B must return twice to cover some register, say RB
Covering State for Two
Write(RB)
B
Write(RA)
A
Art of Multiprocessor Programming
123
Covering State for Two
• Start with B covering register RB for the 1st time • Run A until it is about to write to uncovered RA
• Are we done?
Write(RB)
B
Write(RA)
A
Art of Multiprocessor Programming
124
Covering State for Two
• NO! A could have written to RB
• So CS no longer looks empty
Write(RB)
B
Write(RA)
A
Art of Multiprocessor Programming
125
Covering State for Two
• Run B obliterating traces of A in RB
• Run B again until it is about to write to RB
• Now we are done
Write(RB)
B
Write(RA)
A
Art of Multiprocessor Programming
126
Inductively We Can Show
• There is a covering state– Where k threads not in CS cover k distinct
registers– Proof follows when k = N-1
• Reference:J. Burns, N. Lynch : Bounds on shared memory for mutual exclusion. Inf. And Comp. 1993
Art of Multiprocessor Programming
127
Summary of Lecture
• In the 1960’s many incorrect solutions to starvation-free mutual exclusion using RW-registers were published…
• Today we know how to solve FIFO N thread mutual exclusion using 2N RW-Registers
Art of Multiprocessor Programming
128
Summary of Lecture
• N RW-Registers inefficient– Because writes “cover” older writes
• Need stronger hardware operations – that do not have the “covering
problem”