Safety Goal:
Liveness Goals:
lock
Pseudocode public void lock() {
int i = ThreadID.get(); // get my ID, 0 or 1
int j = 1 - i; // other thread's ID
flag[i] = true; // set my flag
victim = i; // set myself to be victim
while (flag[j] && victim == i) {
// wait
}
}
unlock
Pseudocode public void unlock() {
int i = ThreadID.get();
flag[i] = false;
}
Showed:
Mutual Exclusion. If both threads concurrently call lock()
, then both cannot return until other calls unlock()
.
Today:
Starvation Freedom. If thread i
calls lock()
then eventually thread i
returns.
Why?
Claim. If thread $A$ calls lock()
, eventually the method will return.
public void lock() {
int i = ThreadID.get(); // get my ID, 0 or 1
int j = 1 - i; // other thread's ID
flag[i] = true; // set my flag
victim = i; // set myself to be victim
while (flag[j] && victim == i) { /*wait*/ }
}
Case 1. $A$ reads flag[B] == false
or victim == B
.
Claim. If thread $A$ calls lock()
, eventually the method will return.
public void lock() {
int i = ThreadID.get(); // get my ID, 0 or 1
int j = 1 - i; // other thread's ID
flag[i] = true; // set my flag
victim = i; // set myself to be victim
while (flag[j] && victim == i) { /*wait*/ }
}
Case 2. $A$ reads flag[B] == true
and victim == A
.
Assumption. After B
obtains lock, B
calls unlock()
public void unlock() {
int i = ThreadID.get();
flag[i] = false;
}
What then happens to thread A
?
The Peterson lock satisfies starvation freedom!
flag
variable signals intent to enter CS
victim
variable signals priority to enter CS
victim = me
means you
have priorityLocks for more threads!
Setup:
0, 1,...,n-1
flag
is Boolean array of size $n$
flag[i] == true
if thread i
wants to obtain locklabel
is integer array of size $n$
label[i]
is priority of thread i
Attempt:
flag[i] = true
label[i] = 1 + max(label[0],...,label[n-1])
label[i]
is smallest label with corresponding flag
set to true
Why won’t this attempt work?
Two processes may see the same set of tickets and take same label:
label[i] == label[j]
for i != j
Solution:
Break ties by ID:
label[i] == label[j]
and i < j
, then i
has priorityUse lexicographic order on pairs (label[i], i)
Is this process fair?
0
…Fields:
boolean[] flag
flag[i] == true
indicates i
would like enter CSint[] label
label[i]
indicates “ticket” number held by i
Initialization:
flag[i] = false
, label[i] = 0
Locking Method:
public void lock () {
int i = ThreadID.get();
flag[i] = true;
label[i] = max(label[0], ..., label[n-1]) + 1;
while (!hasPriority(i)) {} // wait
}
The method hasPriority(i)
returns true
if and only if there is no k
such that
flag[k] == true
andlabel[k] < label[i]
or label[k] == label[i]
and k < i
Just lower your flag:
public void unlock() {
flag[ThreadID.get()] = false;
}
public void lock () {
int i = ThreadID.get();
flag[i] = true;
label[i] = max(label[0], ..., label[n-1]) + 1;
while (!hasPriority(i)) {} // wait
}
Why?
label
before $B$ calls lock()
,public void lock () {
int i = ThreadID.get();
flag[i] = true;
label[i] = max(label[0], ..., label[n-1]) + 1;
while (!hasPriority(i)) {} // wait
}
Why?
Thread i
calls lock()
:
i
writes label[i]
lock()
by j != i
have lower priorityk
ahead of i
eventually releases lockSo:
i
eventually servedpublic void lock () {
int i = ThreadID.get();
flag[i] = true;
label[i] = max(label[0], ..., label[n-1]) + 1;
while (!hasPriority(i)) {} // wait
}
Suppose not:
Since $B$ entered CS:
Former can not happen: labels strictly increasing
Lamport’s Bakery Algorithm:
Two Issues:
hasPriority
method is costly0, 1,...
long
valuesHomework 2 will have questions that address these issues.
We cannot do better:
If $n$ threads want to achieve mutual exclusion + deadlock-freedom, must have $n$ read/write registers (variables)
lock()
requires 1,000s of readshasPriority
requires either 1,000s of reads or a more advanced data structureArgument relies crucially on fact that the only atomic operations are read
and write
Modern computers offer more powerful atomic operations
In Java, AtomicInteger
class
getAndIncrement()
is supported atomic operationHomework 2 Use AtomicInteger
s to get a cleaner and more efficient realization of Lamport’s bakery idea.
Vector operations!