Queue locks,( Array based locks, CLH, MCS Queue locks, composite locks) Flashcards
Why are queue locks good?
Cache-coherence traffic is reduced since each thread spins on a different location.
increase CS utilization
fair
variables in Alock class
class ALock implements Lock {
boolean[] flags={true,false,…,false};
AtomicInteger tail
= new AtomicInteger(0);
ThreadLocal<Integer> mySlot;</Integer>
Lock code for Alock
public lock() {
mySlot = tail.getAndIncrement();
while (!flags[mySlot]) {};
}
unlock for Alock
public unlock() {
flags[mySlot] = false;
flags[(mySlot+1)] = true;
}
What is good/bad about Alock
scalable,simple
not space efficient
1bit per thread
What keeps track of the queue in CLH?
Linked List
What are the 2 states of the CLH and what do they mean
true: has/want to acquire lock
false: finished + has released it
What does each node have in a CLH
a track of its predecessors status
Variables in CLH
class CLHLock implements Lock {
AtomicReference<Qnode> tail;
ThreadLocal<Qnode> myNode
= new Qnode();
}}</Qnode></Qnode>
lock CLH
public void lock() {
myNode.locked = true;
Qnode pred
= tail.getAndSet(myNode);
while (pred.locked) {}
}
unlock CLH
public void unlock() {
myNode.locked.set(false);
myNode = pred;
}
Whats good about CLH
Lock release affects predecessor only
small, constant-sized space
MCS Lock idea
FIFO
Spin on local memory only
small, constant-size overhead
Difference between CLH and MCS
in CLH = implicit MCS = explicit
each node in the queue has a next field
how does the Node look for MCS
class Qnode {
boolean locked = false;
qnode next = null;
}
What variables does MCS lock have?
only tail (atomic reference)
lock MCS
public void lock() {
Qnode qnode = new Qnode();
Qnode pred = tail.getAndSet(qnode);
if (pred != null) {
qnode.locked = true;
pred.next = qnode;
while (qnode.locked) {}
}}
unlock MCS
public void unlock() {
if (qnode.next == null) {
if (tail.CAS(qnode, null)
return;
while (qnode.next == null) {}
}
qnode.next.locked = false;
}
What 2 types of locks do composite locks use?
Backoff + Queue
Idea of Composite locks
Keep small number of waiting threads in a queue and have the rest use exponential backoff
how will the Composite lock work?
keep fixed sized array of lock nodes
Each thread that tries to acquire the lock selects array node at random.
if in use back off and try again
If node is acquired enqueue in TOLock style queue
wait till its your turn to enter CS
node states in Composite lock and what do they mean
FREE = available
WAITING = linked into the queue and either in/waiting CS
RELEASED = owner leaves the CS
ABORTED = quit
how does a thread try to acquire a lock in a CLock?
Acquire node in waiting array
enqueue node in queue
waits until node reaches head of the queue
What does tail point to in CLock?
either null or last value entered into queue
what are the 2 variables in the CLock?
tail (AtomicReference<Qnode>)
Qnode[] waiting</Qnode>
how does the states look in CLock
enum State {FREE, WAITING, RELEASED,
ABORTED}
How does the node class look(for the composite lock)?
class Qnode {
AtomicReference<State> state;
Qnode pred;
public Qnode() {
state = new
AtomicReference<State>
(State.FREE);
}</State></State>
How does the tryLock look in CLock?
public boolean tryLock() {
Qnode node = acquireNode();
Qnode pred = spliceNode(node);
waitForPredecessor(pred, node);
}
To aquire a node at random how does the function look in CLock
private Qnode acquireNode() {
Qnode node = waiting[random.nextInt()];
while (true) {
if (state.compareAndSet(FREE, WAITING))
return node;
currTail = tail;
if (state == ABORTED || state ==
RELEASED) {
if (node == currTail) {
Qnode myPred = null;
if (state == ABORTED)
myPred = node.pred;
if (tail.compareAndSet(
currTail, myPred)
node.state.set(WAITING);
return node;
}
}
how is the node spliced into the queue in CLock?
private Qnode spliceNode(Qnode node) {
Qnode currTail;
do {
currTail = tail;
if (timeout()) {
node.state.set(FREE);
throw new TimeoutException();
}
} while (!tail.compareAndSet(currTail,
node);
return currTail;
}
how does a node wait for its predecessor in CLock?
private void waitforPredecessor {
if (pred == null)
return;
State predState = pred.state.get();
while (predState != RELEASED) {
if (predState == ABORTED) {
Qnode temp = pred;
pred = pred.pred;
temp.state.set(FREE);
}
if (timeout()) {
node.pred = pred;
node.state.set(ABORTED);
} throw new TimeoutException();
predState = pred.state.get();
}
pred.state.set(FREE);
return;
}
unlock for CLock
public void unlock() {
myNode.state.set(RELEASED);
}