Download presentation
Presentation is loading. Please wait.
1
Distributed Algorithms (22903)
Lock-free stack algorithms Lecturer: Danny Hendler
3
Concurrent Objects Each object has a state
Usually given by a set of shared memory fields Objects may be implemented from simpler base objects Each object supports a set of operations Only way to manipulate state E.g. – a shared counter supports the fetch&increment operation 3
4
Shared Objects Correctness
Correctness of a sequential counter fetch&increment, applied to a counter with value v, returns v and increments the counter’s value to (v+1). Values returned by consecutive operations: 0, 1, 2, … But how shall we define the correctness of a shared counter?
5
Shared Objects Correctness (cont’d)
Invocation Response fetch&inc q.enq(x) fetch&inc q.enq(y) fetch&inc q.deq(y) fetch&inc q.deq(x) time time There is only a partial order between operations!
6
Shared Objects Correctness (cont’d)
A sequential object history is a sequence of matching invocations and responses on the object. Example: a sequential history of a FIFO queue q.enq(3) q:void q.enq(7) q.deq() q:3 q.deq() q:7
7
Sequential specification
The correct behavior of the object in the absence of concurrency: a set of legal sequential object histories. Example: the sequential spec of a counter H0: H1: c.f&i() c:0 H2: c.f&i() c:0 c.f&i() c:1 H3: c.f&i() c:0 c.f&i() c:1 c.f&i() c:2 H4: c.f&i() c:0 c.f&i() c:1 c.f&i() c:2 c.f&i() c:
8
Shared Objects Correctness (cont’d)
Linearizability An execution is linearizable if there exists a permutation of the operations on each object o, , such that: is a sequential history of o preserves the partial order of the execution.
9
Example linearizable q.enq(x) q.enq(x) q.deq(y) q.deq(y) q.enq(y)
q.deq(x) q.deq(x) time time
10
Example not linearizable q.enq(x) q.enq(x) q.deq(y) q.enq(y) q.enq(y)
time
11
Wait-freedom vs. lock-freedom
Wait-freedom – each process completes its operation on the in a finite number of its own steps Lock-freedom – some process completes its operation on the object after a finite number of steps is taken
12
The compare&swap operation
Comare&swap(b,old,new) atomically v read from b if (v = old) { b new return success } else return failure; Motorola 680x0 IBM 370 Sun SPARC 80X86 MIPS PowerPC DECAlpha 12
13
Treiber’s stack algorithm
… val val val Top next next next Push(int v, Stack S) n := new NODE ;create node for new stack item n.val := v ;write item value do forever ;repeat until success node top := S.top n.next := top ;next points to current (LIFO order) if compare&swap(S, top, n) ; try to add new item return ; return if succeeded od
14
Treiber’s stack algorithm (cont’d)
… val val val Top next next next Pop(Stack S) do forever top := S.top if top = null return empty if compare&swap(S, top, top.next) return top.val od
15
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.
16
… An elimination backoff stack algorithm
(Hendler, Shavit and Yerushalmi, 2004) Key idea: pairs of push/pop operations may collide and eliminate each other without accessing a central stack. Central stack … val val val Top next next next collision array
17
… Collision scenarios Collision array Central stack push pop push pop
val val val Top next next next
18
Elimination: challenges
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… Collision array push pop Top val next … Central stack
19
Data structures Location array collision array
Each stack operation is represented by a ThreadInfo structure struct ThreadInfo { id ;the identifier of the thread performing the operation op ;a PUSH/POP opcode cell ;a cell structure spin ;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 p4 pn Thread Info Thread Info collision array p1 p7
20
Elimination-backoff stack code
void StackOp(ThreadInfo* p) { if (TryPerformStackOP(p) == FALSE) ;if operation not applied to central stack LesOp(p) ;try to eliminate operation by colliding with an opposite-type operation return void LesOP(ThreadInfo * p) while (1) location[mypid]=p ;announce arrival pos=GetPosition(p) ;get a random position at the collision array him=collision[pos] ;read current value of that position while (!compare&swap(&collision[pos],him,mypid);try to write own ID him=collision[pos] ;continue till success if (him != empty) ;if read an ID of another thread q=location[him] ;read a pointer to the other thread’s info if (q!=NULL && q->id=him && q->op != p->op) ;if may collide if (compare&swap(&location[mypid],p,NULL) ;try to prevent unwanted collisions if (TryCollision(p,q)==true) ;if collided successfully return ;return code is already at ThreadInfo structure else goto stack ;try to apply operation to central stack else FinishCollision(p), return ;extract information and finish delay (p->spin) ;Wait for other thread to collide with me if (!compare&swap(&location[mypid],p,NULL) ;if someone collided with me FinishCollision(p), return;Extract information and finish stack: if (TryPerformStackOp(p)==TRUE) return ;try to apply operation to central stack
21
Elimination-backoff stack code (cont’d)
void TryCollision(ThreadInfo* p, ThreadInfo *q) if (p->op==PUSH) if (compare&swap(&location[him],q,p)) ;give my record to other thread return TRUE else return FALSE if (compare&swap(&location[him],q,NULL)) p->cell=q->cell ;get pointer to PUSH operation’s cell location[mypid]=NULL; I will not have time to go over this code… void FinishCollision(ThreadInfo* p) if (p->op==POP) p->pcell=location[mypid]->pcell location[mypid]=NULL
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.