Transcript here
Concurrent Stacks and Elimination Based on chapter 11 of The Art of Multiprocessor Programming Stack • LIFO top D E F value next Push() method G top D E F Pop() method top D E F What we’ll see today • An unbounded lock-free stack • Elimination Backoff stack Lock-free Stack - Push oldTop D node G top.CompareAndSet (oldTop, node) top D E F Lock-free Stack – Push Lock-free Stack - Pop oldTop D newTop top.CompareAndSet (oldTop, newTop) top D E F Lock-free Stack - Pop Lock-free Stack – Features • Lock-free • Linearizable • No ABA problem – thanks to the Java garbage collector But.. • Scales poorly – stack top is a sequential bottleneck (And backoff doesn’t help with that) Elimination • Observation: A push() followed by a pop() leave the stack unchanged. • The two calls eliminate each other. Elimination Backoff Stack Pop() top Pop() Push(B) D E F Reminder: Atomic Stamped Reference • CompareAndSet(T expectedRef, T newRef, int expectedStamp, int newStamp) • T get(int[] stampHolder) • Void Set(T newReference, int newStamp) Exchanger Reference T Stamp Status (Enum) T Exchange(T myItem,long timeout) Exchanger – Initial state Reference Null Stamp EMPTY Exchanger – First Thread Arrives YourItem Stamp CompareAndSet (yourItem, myItem, EMPTY, WAITING) Reference Stamp EMPTY Null Null EMPTY MyItem Item1 Exchanger – First Thread Arrives YourItem Stamp Null EMPTY Reference Item1 Stamp WAITING MyItem Item1 Exchanger – Second Thread Arrives YourItem YourItem Stamp Stamp CompareAndSet (yourItem, myItem, Item1 WAITING WAITING, BUSY) Reference Item1 MyItem Item2 Stamp WAITING WAITING MyItem Item1 Exchanger – Second Thread Arrives YourItem Item1 Stamp WAITING CompareAndSet (yourItem, null, BUSY, EMPTY) Reference Item2 YourItem Stamp Stamp BUSY BUSY YourItem MyItem Item2 Item1 Exchanger – First Thread Finishes Reference Null YourItem Stamp Item2 BUSY Stamp EMPTY MyItem Item1 Exchanger – Initial state (Scenario 2) Reference Null Stamp EMPTY Exchanger – First Thread Arrives YourItem Reference Stamp Stamp EMPTY Null Null EMPTY MyItem Item1 Exchanger – Second Thread Arrives YourItem Stamp YourItem CompareAndSet (yourItem, myItem, EMPTY, WAITING) Reference Null Null MyItem Item2 Stamp Null EMPTY Stamp EMPTY EMPTY MyItem Item1 Exchanger – First Thread Reads the value YourItem Stamp CompareAndSet Item2 WAITING (yourItem, myItem, WAITING, BUSY) Reference Item2 Item2 YourItem Stamp Stamp WAITING WAITING YourItem MyItem Item2 Item1 Exchanger – 3rd Thread Arrives YourItem Item3 Stamp BUSY CompareAndSet (yourItem, myItem, WAITING, BUSY) Reference Item2 Item3 Item3 YourItem Stamp Item2 WAITING Stamp WAITING BUSY BUSY MyItem MyItem Item2 Item1 Exchanger • Allows exactly two threads to exchange values (possibly null). • After both threads returned from exchange(), they each hold the other’s value. • Lock Free – The only way it can fail is if others repeatedly succeeded or no one showed up. • Linearizable • No ABA problem Elimination Array Elimination Backoff Stack - Push ` Elimination Backoff Stack - Pop RangePolicy • Thread local – each thread has its own policy • Records successful exchanges, timeout failures • (but not failures caused by operations mismatch). • Possible policy: smaller range when timeout failures are often and vice versa. Elimination Backoff Stack - Summary • Lock- Free • Linearizable • Scaleable – As the load increases, the number of successful eliminations will grow (more operations complete in parallel). • Contention at the LockFreeStack is reduced – eliminated operations never access the stack.