310 likes | 448 Views
Common2 extended to stacks and unbound concurrency. By: Yehuda Afek Eli Gafni Adam Morrison May 2007 Presentor: Dima Liahovitsky. 1. Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary. 2.
E N D
Common2 extended to stacks and unbound concurrency By: Yehuda Afek Eli Gafni Adam Morrison May 2007 Presentor: Dima Liahovitsky 1
Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary 2
Refresh: TAS TAS object: boolean variable state, initally TRUE Test-and-set() v := state; state := false; return v; 3
Refresh: F&A F&A object: int variable num, initialised at the begining Fetch-and-add(x) v := num; num := v + x; return v; 4
Refresh: wait-freedom Definition: an algorithm is wait-free if a process invoking it will finish after a finite number of steps. 5
Refresh: linearization, concurrency Let H be a history of execution of the system: a sequence of invocation and response events. H is linearizable if H is equivalent to some valid sequential history S, meaning that the partial order of operations in H is a sub-set of the partial order of operations in S. Such a S is the linearization of H. If two operations o1, o2 are incompatible by the partial order on operations induced by a history H, we say: o1 and o2 are concurrent. 6
St.push(a) St.pop(a) St.push(b) St.pop(b) time Refresh: linearization (cntd.) linearizable St: Concurrent operations Linearization points not linearizable St.push(x) St.push(y) St.pop(x) St.pop(y) Example: Stack 7
Refresh: consensus Consensus object: Operation: decide(xi), returns a value Supports: Agreement: all processes calling for decide() get the same return value Validity: the value returned to processes from decide() must be an input of one of them 8
Refresh: consensus (cntd.) Consensus power of object obj: The largest number of processes that can wait-free reach consensus using copies of obj object, and registers. Consensus power k k-consensus Consensus hierarchy: K-consensus object cannot implement (k+1)-consensus object 9
Common2 Definition (by Y. Afek, 1993): Family of objects that are wait-free implementable from 2-consensus objects for any number of processes. It has been known that F&A, TAS are inside Common2. It has been believed that not FIFO queue nor LIFO stack are inside Common2. Hmmmmmm… maybe stack IS inside Common2?.. 10
Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary 11
Wait-free STACK Shared Items: range: F&A object initialized to 1 //index for the next push items: array [1…] of registers //items[0] = $ T: array [1…] of TAS object Pop() { 1. t = F&A(range, 0) - 1; 2. for i = t downto 1 3. X = items[i]; 4. If x != null then { 5. IfTAS(T[i]) thenreturn x; } // end if } // end for 6. return $; //indicator of empty stack } // end Pop Push(x) { 1. i = F&A(range, 1); 2. items[i] = x; } 12
Wait-free STACK Let’s have a look at our implementation… • Wait-free? • Implemented from registers and 2-consensus objects? • It’s also known that TAS and F&A have n-bounded implementations from 2-consensus objects • Therefore if we show that our stack is linearizable, then we can proudly say that: The Stack object has an n-bounded wait-free implementation from registers and 2-consensus objects => our Stack is in Common2, by definition. yes! yes! 13
time Wait-free STACK Linearization proof sketch: 1. Eliminating concurrent Push(x)/Pop(x) from the History St.push(x) St.pop(x) Just delete concurrent push(x)/pop(x) ?... Dummy-push(x) { //like previus Push(x), but without array modification i := F&A(range, 1); } 14
Linearization proof sketch: 2. Linearizing the rest of the history (without concurrent push(x) / pop(x)): Variables for linearization algorithm: I : array of values, initially I[0] = $ and all other cells are NULL S: history, initially empty Terms for the linearizing algorithm L: top(I) : value in the highest index non-NULL cell of I 15
Linearization proof sketch: 2. Linearizing the rest of the history (without concurrent push(x) / pop(x)): L(History = <e1,…,eh>) { for j := 1 to h do { if ej = <items[i] := x> { // push() response I[i] := x let y be the lowest non-NULL item stored above x in I if no such y exists then S := S o Push(x) else { let S = S1o Push(y) o S2 S := S1o Push(x) Push(y) o S2 } //end else } //end if while Pop(top(I)) is active in e1…ej { let v = top(I) S := S o Pop(v) If v != $ then I[index(v)] := NULL } //end while } //end for } //end L 16
Midway Conclusions: So what have we proved for now? There is an n-bounded wait-free stack implementation from registers and 2-consensus objects (TAS, F&A) . Therefore stack is in Common2. What next? If we show unbounded concurrency TAS and F&A implementations from registers and 2-consensus objects… Then we will automatically get an unbounded concurrency wait-free stack implementation from registers and 2-consensus objects. 17
Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary 18
Snapshot object Each object has a “segment” = SWMR register. A process may obtain an “atomic snapshot” of all segments of other processes. Supports two operations: update(v) : a process updates its segment to v Scan(): returns an n-element vector called “view” (or V[]), with a value of each segment of all n processes V[i] must return the value of the latest update() of process i. scan() returns a “snapshot” of the segments array that existed at some point during the execution. 19
Snapshot example time P1.seg P2.seg P3.seg quantums 1 0 0 0 2 1 0 0 3 2 0 0 4 2 1 0 5 2 1 3 Scan() starts here Scan() ends here V[i] must return the value of the latest update() of process i. scan() returns a “snapshot” of the segments array that existed at some point during the execution. 3 processes: P1, P2, P3 one Possible snapshot returned from scan(): <2,1,0> Not possible snapshots returned from scan(): <0,0,0> <1,1,0> 20
Atomic write-and-snapshot We introduce one-shotn-bounded write-and-snapshot() implementation. The implementation can be easily turned into long-lived one by having each process P simulate a sequence P1, P2, ... of different processes in the one-shot implementation, where Pi performs the i-th operation of P. Write-and-snapshot(inputi) makes update() and scan() in one procedure. When process i calls write-and-snapshot(), it first updates its segment, and then returns a set of segments of all other processes that have already updated their segments. Therefore if process i is the first process to complete write-and-snapshot(), it’ll receive an empty set from write-and-snapshot(). 21
Atomic write-and-snapshot Simpler to understand n-bounded implementation Shared variables: T[1..n] : array of TAS objects level[1..n] : array of swmr registers; initialized to n+1 value[1..n] : array of swmr registers Local variable: S : set of at most n integers; t : stores returned value of result of TAS Write-and-snapshot(inputi) { 1. value[i] := inputi; 2. while(TRUE) do { 3. level[i] := level[i] – 1; 4. S := { j | level[j] <= level[i] } 5. If |S| >= level[i] then { 6. t := TAS(T[level[i]]); 7. If t=TRUE then // if we won TAS 8. return { value[j] | j of S }; } //if } //while } // write-and-snapshot There exists unbounded concurrency wait-free implementation 22
Issues for unbounded concurrency write-and-snapshot There exists an algorithm that solves these issues, and therefore implements unbounded concurrency write-and-snapshot(). We are going to use this unbounded concurrency write-and-snapshot() to implement unbounded concurrency F&A… How does a process determine in which level to start its descent? How does a process decide when to stop at some level and return from there? How does a process that decides to stop at level L find out which processes are active in the levels below it, in order to return them as its immediate snapshot? 23
Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary 24
Unbounded concurrency F&A Shared variables: WS : write-and-snapshot object args: array[1,…] of registers, initially empty Fetch-and-add(kp){ //invoked by process P 1. args[P] := kp; 2. S := WS.write-and-snapshot(); //unbounded concurrency WAS 3. return ∑Q∈S,Q!=P (args[Q]) ; } //end of F&A A process P announces its input. (line 1) P then obtains an atomic write-and-snapshot Sp (line 2), and returns the sum of all inputs announced in Sp (line 3). 25
Unbounded concurrency TAS There is an easy implementation of TAS from F&A, Therefore… 26
Unbounded concurrency STACK Shared Items: range: F&A object initialized to 1 //index for the next push items: array [1…] of registers //items[0] = $ T: array [1…] of TAS object Pop() { 1. t = F&A(range, 0) - 1; 2. for i = t downto 1 3. X = items[i]; 4. If x != null then { 5. IfTAS(T[i]) thenreturn x; } // end if } // end for 6. return $; //indicator of empty stack } // end Pop Push(x) { 1. i = F&A(range, 1); 2. items[i] = x; } Stack has an unbounded concurrency wait-free implementation from registers and 2-consensus objects 27
Outline: Introduction, refresh and definitions Wait-free stack implementation Snapshot objects Unbounded concurrency objects Summary 28
Summary We showed a wait-free stack implementation in n-bounded concurrency model, meaning that stack object is inside Common2, refuting the previous conjecture that such an implementation is impossible. We introduced an unbounded concurrency write-and-snapshot object, using which we easily got unbounded concurrency F&A object, using which we’ve also got unbounded concurrency TAS object. Back to our stack, the last discovery immediately makes our stack implementation an unbounded concurrency wait-free implementation from registers and 2-consensus objects. 29
Summary Open problems: Common2 membership problem (whether every consensus power 2 object can be wait-free implemented from 2-consensus) remains open. The previous conjecture that a FIFO queue object cannot be implemented wait-free from Common2 objects, is not proven yet. Is there a natural object that is wait-free implementable from 2-consensus in the n-bounded concurrency model, but is not implementable for unbounded concurrency model? Our conjecture is that swap object is one such an object. 30
Thank you! 31