victim - PARSA

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