Title: Mutual Exclusion
1Mutual Exclusion
2Critical Section
- class Counter
- private int value 1 //counter starts at
one - public Counter(int c) //constructor
initializes counter - value c
-
- public int inc() //increment
value return prior value - int temp value //start of danger
zone - value temp1 //end of danger zone
- return temp
3Critical Section
- The problem occurs if two threads both read the
value field at the line marked start of danger
zone, and then both update that field at the
line marked end of danger zone.
int temp value value temp1
4Critical Section
2
3
2
Value
int temp value value temp1
read 1
read 2
write 2
write 3
read 1
write 2
time
5The mutual exclusion problem
remainder code
The problem is to design the entry and exit code
in a way that guarantees that the mutual
exclusion and deadlock-freedom properties are
satisfied.
entry code
critical section
exit code
6Good properties
- Mutual Exclusion No two threads are in their
critical sections at the same time. - Deadlock-freedom If a thread is trying to enter
its critical section, then some thread, not
necessarily the same one, eventually enters its
critical section. - Starvation-freedom If a thread is trying to
enter its critical section, then this thread must
eventually enter its critical section. - Starvation-freedom is a stronger property than
Deadlock-freedom.
7Discussion Topics
- The mutual exclusion problem and proposed
algorithms - Petersons algorithm
- Kessels single-writer algorithm
- Tournament algorithms
- The Filter algorithm
- The Bakery algorithm
8Proposed solutions for two threads
- We begin with two inadequate
- but interesting algorithms
9Some notations
- A ? B
- event A precedes event B
- CSA
- thread A is in the critical section
- writeA(xv)
- the event in which thread A writes to x
- readA(xv)
- the event in which thread A reads from x
10Algorithm 1
Thread 0 flag0 true while (flag1) critical section flag0false Thread 1 flag1 true while (flag0) critical section flag1false
11Mutual Exclusion
- Algorithm 1 satisfies
- mutual exclusion
12Proof
- Assume in the contrary that two threads can be in
their critical section at the same time. - From the code we can see
- write0(flag0true) ? read0(flag1false) ?
CS0 - write1(flag1true) ? read1(flag0false) ?
CS1 - From the assumption
- read0(flag1false) ? write1(flag1true)
Thread 0 flag0 true while (flag1) critical section flag0false Thread 1 flag1 true while (flag0) critical section flag1false
13Proof
- We get
- write0(flag0true) ? read0(flag1false) ?
write1(flag1true) ? read1(flag0false) - That means that thread 0 writes (flag0true)
and then thread 1 reads that (flag0false), a
contradiction.
Thread 0 flag0 true while (flag1) critical section flag0false Thread 1 flag1 true while (flag0) critical section flag1false
14Deadlock freedom
- Algorithm 1 fails dead-lock freedom
- Concurrent execution can deadlock.
- If both threads write flag0true and
flag1true before reading (flag0) and
(flag1) then both threads wait forever.
Thread 0 flag0 true while (flag1) critical section flag0false Thread 1 flag1 true while (flag0) critical section flag1false
15Algorithm 2
Thread 0 victim 0 while (victim 0) critical section Thread 1 victim 1 while (victim 1) critical section
16Mutual Exclusion
- Algorithm 2 satisfies
- mutual exclusion
17Proof
- Assume in the contrary that two threads can be in
their critical section at the same time. - From the code we can see
- write0(victim0) ? read0(victim1) ?CS0
- write1(victim1) ? read1(victim0) ? CS1
Thread 0 victim 0 while (victim 0) critical section Thread 1 victim 1 while (victim 1) critical section
18Proof
- Since thread 1 must assign 1 to victim between
the events write0(victim0) and read0(victim1),
and since this assignment is the last, we get - write0(victim0) ? write1(victim1) ?
read0(victim1) - Once victim is set to 1, it does not change, so
every read will return 1, and this is a
contradiction to the former equation - write1(victim1) ? read1(victim0) ? CS1
Thread 0 victim 0 while (victim 0) critical section Thread 1 victim 1 while (victim 1) critical section
19Deadlock freedom
- Algorithm 2 also fails deadlock freedom.
- It deadlocks if one thread runs completely before
the other.
Thread 0 victim 0 while (victim 0) critical section Thread 1 victim 1 while (victim 1) critical section
20Algorithms for Two Threads
- Well describe two algorithms that solve the
mutual exclusion problem for two Threads. They
are also deadlock-free and starvation free.
21Petersons Algorithm
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
22Petersons Algorithm
- 0/1 indicates that the thread is contending for
the critical section by setting flag0/flag1
to true. - victim shows who got last
- Then if the value of flagi is true then there
is no contending by other thread and the thread
can start executing the critical section.
Otherwise the first who writes to victim is also
the first to get into the critical section
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
23Schematic for Petersons mutual exclusion
algorithm
Indicate contending flagi true
- The structure shows that the
- first thread to cross the barrier is
- the one which gets to enter the
- critical section. When there is no
- contention a thread can enter the
- critical section immediately.
Barrier victim i
no / maybe
First to cross the barrier? victim j ?
Contention? flagj true ?
yes
no
yes
critical section
exit code flagi false
24Mutual Exclusion
- Petersons algorithm
- satisfies mutual exclusion
25Proof
- Assume in the contrary that two threads can be in
their critical section at the same time. - From the code we see
- () write0(flag0true) ? write0(victim0) ?
read0(flag1) ? read0(victim) ? CS0 -
- write1(flag1true) ? write1(victim1) ?
read1(flag0) ? read1(victim) ? CS1
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
26Proof
- Assume that the last thread to write to victim
was 0. Then - write1(victim1) ? write0(victim0)
- This implies that thread 0 read that victim0 in
equation () - Since thread 0 is in the critical section, it
must have read flag1 as false, so - write0(victim0) ? read0(flag1false)
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
27Proof
- Then, we get
- write1(flag1true) ? write1(victim1) ?
- write0(victim0) ? read0(flag1false)
- Thus
- write1(flag1true) ? read0(flag1false)
- There was no other write to flag1 before the
critical section execution and this yields a
contradiction.
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
28Starvation freedom
- Petersons algorithm
- is starvation-free
29Proof
- Assume to the contrary that the algorithm is not
starvation-free - Then one of the threads, say thread 0, is forced
to remain in its entry code forever
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
30Proof
- This implies that at some later point thread 1
will do one of the following three things - 1. Stay in its remainder forever
- 2. Stay in its entry code forever, not
succeeding and - proceeding into its critical section
- 3. Repeatedly enter and exit its critical section
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
Well show that each of the three possible cases
leads to a contradiction.
31Proof
- In the first case flag1 is false, and hence
thread 0 can proceed. - The second case is impossible since victim is
either 0 or 1, and hence it always enables at
least one of the threads to proceed. - In the third case, when thread 1 exit its
critical section and tries to enter its critical
section again, it will set victim to 1 and will
never change it back to 0, enabling thread 0 to
proceed.
Thread 0 flag0 true victim 0 while (flag1 and victim 0) skip critical section flag0 false Thread 1 flag1 true victim 1 while (flag0 and victim 1) skip critical section flag1 false
32Kessels single-writer Algorithm
- What if we replace the multi-writer register
victim with two single- - writer registers. What is new algorithm?
Answer (Kessels Alg.) victim 0 ? victim0
victim1 victim 1 ? victim0 ?victim1
33Kessels single-writer Algorithm
Thread 0 flag0 true local0 victim1 victim0 local0 while (flag1 and local0victim1) skip critical section flag0 false Thread 1 flag1 true local11-victim0 victim1 local1 while (flag0 and local1 ? victim0)) skip critical section flag1 false
Thread 0 can write the registers victim0 and
flag0 and read the registers victim1 and
flag1 Thread 1 can write the registers
victim1 and flag1 and read the registers
victim0 and flag0
34Solutions for Many Threads
- How can we use a two-thread algorithm to
construct an algorithm for many threads?
35Tournament Algorithms
1
2
3
4
5
6
7
8
36Tournament Algorithms
- A simple method which enables the construction an
algorithm for n threads from any given algorithm
for two threads. - Each thread is progressing from the leaf to the
root, where at each level of the tree it
participates in a two thread mutual exclusion
algorithm. - As a thread advanced towards the root, it plays
the role of thread 0 when it arrives from the
left subtree, or of thread 1 when it arrives from
the right subtree.
37The Filter Algorithm for n Threads
- A direct generalization of Petersons algorithm
to multiple threads. - The Peterson algorithm used a two-element boolean
flag array to indicate whether a thread is
interested in entering the critical section. The
filter algorithm generalizes this idea with an
N-element integer level array, where the value of
leveli indicates the latest level that thread i
is interested in entering.
ncs
cs
level n-1
38Filter
- 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
level 0
cs
level n-1
39The Filter Algorithm
Thread i for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
40Filter
Thread i for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
One level at a time
41Filter
Thread i for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
Announce intention to enter level L
42Filter
Thread i for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
Give priority to anyone but me (at every level)
43Filter
Thread i for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
Wait as long as someone else is at same or higher
level, and Im designated victim.
Thread enters level L when it completes the loop.
44Claim
- There are at most n-L threads enter level L
- Proof by induction on L and by contradiction
- At L0 trivial
- Assume that there are at most n-L1 threads at
level L-1. - Assume that there are n-L1 threads at level L
- Let A be the last thread to write victimL and B
any other thread at level L
45Proof structure
ncs
Assumed to enter L-1
A
B
n-L1 4
n-L1 4
Last to write victimL
cs
By way of contradiction all enter L
Show that A must have seen B at level L and
since victimL A could not have entered
46Proof
- From the code we get
- From the assumption
writeB(levelBL)?writeB(victimLB)
writeA(victimLA)?readA(levelB)
writeB(victimLB)?writeA(victimLA)
for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
47Proof
- When combining all we get
- Since B is at level L, when A reads levelB, it
reads a value greater than or equal L and so A
couldnt completed its loop and still waiting
(remember that victimA), a contradiction.
writeB(levelBL)
?readA(levelB)
for (int L 1 L lt n L) leveli L victimL i while (( k ! i levelk gt L) and victimL i ) critical section leveli 0
48A conclusion
- The filter algorithm satisfies
- mutual exclusion
- At level n-1 there are at most n-(n-1)1 threads,
which means at most one thread in the critical
section
49Starvation-freedom
- Filter Lock satisfies properties
- Just like Peterson algorithm at any level
- So no one starves
50Fairness
- Starvation freedom guarantees that if a thread is
trying to enter its critical section, it will
eventually do so - There is no guarantee about how long it will take
- We wish for fairness if thread A enters the
entry code before thread B, then A should enter
the critical section first
51Bounded waiting
- We divide our method into two parts
- Doorway interval
- - Written DA
- - always finishes in finite steps
- Waiting interval
- - Written WA
- - may take unbounded steps
remainder
entry code
critical
section
exit code
52The mutual exclusion problem
- Mutual Exclusion
- Deadlock-freedom
- Starvation-freedom
- FIFO
53r-Bounded Waiting
- For threads A and B
- If DAk ? DB j
- As k-th doorway precedes Bs j-th doorway
- Then CSAk ? CSBjr
- As k-th critical section precedes Bs (jr)-th
critical section - B cannot overtake A by more than r times
- First-come-first-served means r 0.
54Fairness in Filter Algorithm
- Filter satisfies properties
- No one starves
- But very weak fairness
- Not r-bounded for any r!
- Thats pretty lame
55Bakery Algorithm
- The idea is similar to a line at the bakery
- A customer takes a number greater than numbers of
other customers - Each of the threads gets a unique identifier
56Bakery Algorithm
- Thread i
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
-
-
57Bakery Algorithm
-
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
Doorway
58Bakery Algorithm
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
Im interested
59Bakery Algorithm
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
Take an number numbers are always increasing!
60Bakery Algorithm
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
Someone is interested
61Bakery Algorithm
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
There is someone with a lower number and
identifier. pair (a,b) gt (c,d) if agtc, or ac and
bgtd (lexicographic order)
62Deadlock freedom
- The bakery algorithm is deadlock free
- Some waiting thread A has a unique least
(numberA,A) pair, and that thread can enter the
critical section
63FIFO
- The bakery algorithm is first-come-first-served
- If DA ? DB then As number is earlier
- writeA(numberA) ? readB(numberA) ?
writeB(numberB) ? readB(flagA) - So B is locked out while flagA is true
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
64Starvation freedom
- The bakery algorithm satisfies deadlock freedom
and first-come-first-served and those properties
implies starvation freedom
65Mutual Exclusion
- Suppose A and B in CS together
- Suppose A has an earlier number
- When B entered, it must have seen
- flagA is false, or
- numberA gt numberB
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
66Mutual Exclusion
- numbers are strictly increasing so
- B must have seen (flagA false)
- numberingB ? readB(flagA) ? writeA(flagA) ?
numberingA - Which contradicts the assumption that A has an
earlier number
- flagitrue
- numberi max(number0, ,numbern-1)1
- while ( k! i
- flagk (numberi,i) gt
(numberk,k)) - critical section
- flagi false
67The End