5.1 KiB
Peterson algorithm (for two processes)
Let's try to enforce MUTEX with just 2 processes.
1st attempt:
lock(i) :=
AFTER_YOU <- i
wait AFTER_YOU != i
return
unlock(i) :=
return
This protocol satisfies MUTEX, but suffers from deadlock (if one process never locks).
2nd attempt:
Initialize FLAG[0] and FLAG[1] to down
lock(i) :=
FLAG[i] <- up
wait FLAG[1-i] = down
return
unlock(i) :=
FLAG[i] <- down
return
Still suffers from deadlock if both processes simultaneously raise their flag.
Correct solution:
Initialize FLAG[0] and FLAG[1] to down
lock(i) :=
FLAG[i] <- up
AFTER_YOU <- i
wait FLAG[1-i] = down OR AFTER_YOU != i
return
unlock(i) :=
FLAG[i] <- down
return
Features:
- it satisfies MUTEX
- it satisfies bounded bypass, with bound = 1
- it requires 2 one-bit SRSW registers (the flags and 1 one-bit MRMW registers (AFTER_YOU)
- Each lock-unlock requires 5 accesses to the registers (4 for lock and 1 for unlock)
MUTEX proof
[!info] Remember that, in the #Correct solution, there is this line:
wait (FLAG[1-i] = down OR AFTER_YOU != i)
. Thus, to access the critical section (thereturn
instruction of thelock
function), the possibilities are just the two discussed above.
How has p0 entered its CS?
a) FLAG[1] = down
, this is possible only with the following interleaving:
!
b) AFTER_YOU = 1
, this is possible only with the following interleaving:
!
Bounded Bypass proof (with bound = 1)
-
If the wait condition is true, then it wins (and waits 0).
-
Otherwise, it must be that
FLAG[1] = UP
ANDAFTER_YOU = 0
(quindi p1 ha invocato il lock e p0 dovrà aspettare). -
If p1 never locks anymore then p0 will eventually read
F[1]
and win (waiting 1). -
It is possible tho that p1 locks again:
- if p0 reads
F[1]
before p1 locks, then p0 wins (waiting 1) - otherwise p1 sets A_Y to 1 and suspends in its wait (
F[0] = up AND A_Y = 1
), p0 will eventually readF[1]
and win (waiting 1).
- if p0 reads
Peterson algorithm (n
processes)
- FLAG now has
n
levels (from 0 to n-1)- level 0 means down
- level >0 means involved in the lock
- Every level has its own AFTER_YOU
Initialize FLAG[i] to 0, for all i
lock(i) :=
for lev = 1 to n-1 do
FLAG[i] <- lev
AFTER_YOU[lev] <- i
wait (∀k!=i, FLAG[k] < lev
OR AFTER_YOU[lev] != i)
return
unlock(i) :=
FLAG[i] <- 0
return
We say that: p_i
is at level h
when it exits from the $h$-th wait \to
a process at level h
is at any level <= h
[!info] What is the
wait
condition actually checking? In the wait condition we check that all other processes are at a lower level.
MUTEX proof
Lemma: for every ℓ \in \{0,\dots,n-1\}
, at most n-ℓ processes are at level ℓ, this implies MUTEX by taking ℓ = n-1
Proof by induction on ℓ
Base (ℓ=0): trivial
Induction (true for ℓ, to be proved for ℓ+1):
- p at level ℓ can increase its level by writing its FLAG at ℓ+1 and its index in
A_Y[ℓ+1]
- let
p_x
be the last one that writesA_Y[ℓ+1]
, soA_Y[ℓ+1]=x
- for
p_x
to pass at level ℓ+1, it must be that∀k≠x. F[k] < ℓ+1
, thenp_x
is the only proc at level ℓ+1 and the thesis holds, since 1<=n-ℓ-1 - otherwise,
p_x
is blocked in the wait and so we have at most n-ℓ-1 processes at level ℓ+1: those at level ℓ, that by induction are at most n-ℓ, except for px that is blocked in its wait.
Starvation freedom proof
Lemma: every process at level ℓ (\leq n-1
) eventually wins \to
starvation freedom holds by taking ℓ=0
.
Reverse induction on ℓ
Base (ℓ=n-1
): trivial
Induction (true for ℓ+1, to be proved for ℓ):
-
Assume a
p_x
blocked at level ℓ (aka blocked in its ℓ+1-th wait)\to \exists k\neq x, F[k]\geqℓ+1 \land A\_Y[ℓ+1]=x
-
If some
p_{y}
will eventually setA\_Y[ℓ+1]
toy
, thenp_x
will eventually exit from its wait and pass to level ℓ+1 -
Otherwise, let
G = \{p_{i}: F[i] \geq ℓ+1\}
andL=\{p_{i}:F[i]<ℓ+1\}
- if
p \in L
, it will never enter its ℓ+1-th loop (as it would writeA_Y[ℓ+1]
and it will unblockp_x
, but we are assuming that it is blocked) - all
p \in G
will eventually win (by induction) and move to L\to
eventually,p_{x}
will be the only one in its ℓ+1-th loop, with all the other processes at level <ℓ+1\to
p_{x}
will eventually pass to level ℓ+1 and win (by induction)
- if
Peterson algorithm cost
n
MRSW registers of\lceil \log_{2} n\rceil
bits (FLAG)n-1
MRMW registers of\lceil \log_{2}n \rceil
bits (AFTER_YOU)(n-1)\times(n+2)
accesses for locking and 1 access for unlocking
It satisfies MUTEX and starvation freedom. It does not satisfy bounded bypass:
- consider 3 processes, one sleeping in its first wait, the others alternating in the CS
- when the first process wakes up, it can pass to level 2 and eventually win
- but the sleep can be arbitrary long and in the meanwhile the other two processes may have entered an unbounded number of CSs
Easy to generalize to k-MUTEX.