Upload
claire-harrison
View
224
Download
0
Embed Size (px)
DESCRIPTION
33 The compare&swap operation Comare&swap(b,old,new) atomically v read from b if (v = old) { b new return success } else return failure; MIPS PowerPC DECAlpha Motorola 680x0 IBM 370 Sun SPARC 80X86
Citation preview
DistributedAlgorithms
(22903)
Lecturer: Danny Hendler
Lock-free stack algorithms
2
Wait-freedom vs. lock-freedom
• Wait-freedom – each process completes its operation in a finite number of its own steps
• Lock-freedom – some process completes its operation after a finite number of steps is taken
33
The compare&swap operationComare&swap(b,old,new)atomically v read from b if (v = old) { b new return success } else return failure;
MIPSPowerPCDECAlpha
Motorola 680x0IBM 370Sun SPARC80X86
4
Treiber’s stack algorithm
Push(int v, Stack S)1. n := new NODE ;create node for new stack item2. n.val := v ;write item value3. do forever ;repeat until success4. node top := S.top5. n.next := top ;next points to current (LIFO order)6. if compare&swap(S, top, n) ; try to add new item7. return ; return if succeeded8. od
Top
valnex
t
valnex
t
… valnex
t
5
Treiber’s stack algorithm (cont’d)
Pop(Stack S)1. do forever2. top := S.top3. if top = null4. return empty5. if compare&swap(S, top, top.next)6. return-val=top.val7. free top8. return return-val9. od
Top
valnex
t
valnex
t
… valnex
t
6
Treiber’s stack algorithm (cont’d)It is easily seen that the alg is
linearizable and lock-free
A disadvantage of the algorithms is that…
It has a sequential bottleneck.
An elimination backoff stack algorithm(Hendler, Shavit and Yerushalmi, 2004)
Key idea:Key idea: pairs of push/pop operations may collide and eliminate each other without accessing a central stack.
Top
valnex
t
valnex
t
… valnex
t
Central stack
collision array
8
Collision scenarios
Collision array
push pop push push
Top
valnex
t
valnex
t
… valnex
t
Central stack
poppush
9
Elimination: challenges
Collision array
push pop push push
Top
valnex
t
valnex
t… val
next
Central stack
poppush
• Prevent elimination chains: e.g., A collides with B, which collides with C…
• Prevent race conditions: e.g., A collides with B, which is already gone…
Data structuresEach stack operation is represented by a ThreadInfo structurestruct ThreadInfo {
id ;the identifier of the thread performing the operationop ;a PUSH/POP opcodecell ;a cell structurespin ; duration to spin}
Struct cell { ;a representation of stack item as in Treiber pnext ;pointer to the next cell
pdata ;stack item}
Location array
p1 p2 p3 pn
ThreadInfo
ThreadInfo
p4
collision arrayp1 p7
11
Elimination-backoff stack codevoid StackOp(ThreadInfo* p) {1. if (TryPerformStackOP(p) == FALSE) ;if operation not applied to central stack2. LesOp(p) ;try to eliminate operation by colliding with an opposite-type operation3. return
void LesOP(ThreadInfo * p)1. while (1)2. location[mypid]=p ;announce arrival3. pos=GetPosition(p) ;get a random position at the collision array4. him=collision[pos] ;read current value of that position5. while (!compare&swap(&collision[pos],him,mypid);try to write own ID6. him=collision[pos] ;continue till success7. if (him != empty) ;if read an ID of another thread8. q=location[him] ;read a pointer to the other thread’s info9. if (q!=NULL && q->id=him && q->op != p->op) ;if may collide10. if (compare&swap(&location[mypid],p,NULL) ;try to prevent unwanted
collisions11. if (TryCollision(p,q)==true) ;if collided successfully12. return ;return code is already at ThreadInfo structure13. else goto stack ;try to apply operation to central stack14. else FinishCollision(p), return ;extract information and finish15. delay (p->spin) ;Wait for other thread to collide with me16. if (!compare&swap(&location[mypid],p,NULL) ;if someone collided with me17. FinishCollision(p), return;Extract information and finishstack: if (TryPerformStackOp(p)==TRUE) return ;try to apply operation to central stack
12
Elimination-backoff stack code (cont’d)void TryCollision(ThreadInfo* p, ThreadInfo *q)1. if (p->op==PUSH)2. if (compare&swap(&location[him],q,p)) ;give my record to other
thread3. return TRUE4. else5. return FALSE6. else7. if (compare&swap(&location[him],q,NULL))8. p->cell=q->cell ;get pointer to PUSH operation’s cell9. return TRUE10. else11. return FALSE
void FinishCollision(ThreadInfo* p)1. if (p->op==POP)2. p->pcell=location[mypid]->pcell3. location[mypid]=NULL
13
Elimination-backoff stack code (cont’d)
Why is this implementation linearizable?
Can a record be recycled once popped from stack?
© Herlihy-Shavit 2007 14
Recycling: Simple Solution• Each thread has a free list of
unused queue nodes• Allocate node: pop from list• Free node: push onto list• Use CAS for atomicity• Deal with underflow somehow …
© Herlihy-Shavit 2007 15
Why Recycling is Hard
Free pool
head tail
Want to rediret head
from grey to red zzz…
© Herlihy-Shavit 2007 16
Why Recycling is Hard
Free pool
zzz
head tail
© Herlihy-Shavit 2007 17
Why Recycling is Hard
Free pool
Yawn!
head tail
© Herlihy-Shavit 2007 18
Why Recycling is Hard
Free pool
CAShead tail
OK, here I go!
© Herlihy-Shavit 2007 19
Final State
Free pool
What went wrong?
head tail
© Herlihy-Shavit 2007 20
The Dreaded ABA Problem
Head pointer has value AThread reads value A
head tail
© Herlihy-Shavit 2007 21
Dreaded ABA continued
zzz Head pointer has value BNode A freed
head tail
© Herlihy-Shavit 2007 22
Dreaded ABA continued
Yawn! Head pointer has value A againNode A recycled & reinitialized
head tail
© Herlihy-Shavit 2007 23
Dreaded ABA continued
CAS succeeds because pointer matcheseven though pointer’s meaning has changed
CAShead tail
© Herlihy-Shavit 2007 24
The Dreaded ABA Problem• Is a result of CAS() semantics (Sun,
Intel, AMD)• Does not arise with
Load-Locked/Store-Conditional (IBM)
© Herlihy-Shavit 2007 25
Dreaded ABA – A Solution• Tag each pointer with a counter• Unique over lifetime of node• Pointer size vs word size issues• Overflow?
– Don’t worry be happy?– Bounded tags
• Other solutions exist (e.g. hazard pointers)