Concurrent Queues Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Concurrent Queues and Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Stacks, Queues, and Linked Lists
Multicore Programming Skip list Tutorial 10 CS Spring 2010.
Wait-Free Queues with Multiple Enqueuers and Dequeuers
1 Chapter 4 Synchronization Algorithms and Concurrent Programming Gadi Taubenfeld © 2014 Synchronization Algorithms and Concurrent Programming Synchronization.
Maged M. Michael, “Hazard Pointers: Safe Memory Reclamation for Lock- Free Objects” Presentation Robert T. Bauer.
Monitors & Blocking Synchronization 1. Producers & Consumers Problem Two threads that communicate through a shared FIFO queue. These two threads can’t.
Barrier Synchronization Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Stacks, Queues, and Deques. 2 A stack is a last in, first out (LIFO) data structure Items are removed from a stack in the reverse order from the way they.
Introduction Companion slides for
Concurrent Queues and Stacks The Art of Multiprocessor Programming Spring 2007.
Linked Lists: Lazy and Non-Blocking Synchronization Based on the companion slides for The Art of Multiprocessor Programming (Maurice Herlihy & Nir Shavit)
Spin Locks and Contention Based on slides by by Maurice Herlihy & Nir Shavit Tomer Gurevich.
Scalable Synchronous Queues By William N. Scherer III, Doug Lea, and Michael L. Scott Presented by Ran Isenberg.
Lecture 6-2 : Concurrent Queues and Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Concurrent Queues Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Art of Multiprocessor Programming1 Concurrent Queues Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified.
Concurrent Queues and Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Concurrent Queues and Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Shared Counters and Parallelism Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Introduction to Lock-free Data-structures and algorithms Micah J Best May 14/09.
ESE Einführung in Software Engineering X. CHAPTER Prof. O. Nierstrasz Wintersemester 2005 / 2006.
CS510 Advanced OS Seminar Class 10 A Methodology for Implementing Highly Concurrent Data Objects by Maurice Herlihy.
Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Concurrent Skip Lists.
Concurrent Queues and Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Stacks, Queues, and Deques
שירן חליבה Concurrent Queues. Outline: Some definitions 3 queue implementations : A Bounded Partial Queue An Unbounded Total Queue An Unbounded Lock-Free.
Two-Process Systems TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: A A AA Companion slides for Distributed Computing.
Multicore Programming
The Animated Sequence Chapter 5.1 in Sketching User Experiences: The Workbook.
Linked Structures See Section 3.2 of the text.. First, notice that Java allows classes to be recursive, in the sense that a class can have an element.
1 Chapter 7 Stacks and Queues. 2 Stack ADT Recall that ADT is abstract data type, a set of data and a set of operations that act upon the data. In a stack,
JAVA MEMORY MODEL AND ITS IMPLICATIONS Srikanth Seshadri
1 CMSC421: Principles of Operating Systems Nilanjan Banerjee Principles of Operating Systems Acknowledgments: Some of the slides are adapted from Prof.
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
Gal Milman Based on Chapter 10 (Concurrent Queues and the ABA Problem) in The Art of Multiprocessor Programming by Herlihy and Shavit Seminar 2 (236802)
Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Multiprocessor Architecture Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Concurrent Stacks Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Futures, Scheduling, and Work Distribution Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit TexPoint fonts used.
Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Concurrent Skip Lists.
Images of pesticides By: Leslie London, University of Cape Town This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5.
Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects MAGED M. MICHAEL PRESENTED BY NURIT MOSCOVICI ADVANCED TOPICS IN CONCURRENT PROGRAMMING,
Shared Counters and Parallelism Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Spin Locks and Contention Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Distributed Algorithms (22903) Lecturer: Danny Hendler Lock-free stack algorithms.
The Relative Power of Synchronization Operations Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Concurrent Skip Lists.
Lecture 9 : Concurrent Data Structures Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Linked Data Structures
Review Array Array Elements Accessing array elements
Monitors and Blocking Synchronization
Concurrent Objects Companion slides for
Concurrent Objects Companion slides for
Distributed Algorithms (22903)
Distributed Algorithms (22903)
Distributed Algorithms (22903)
Concurrent Queues and Stacks
Byzantine-Resilient Colorless Computaton
Concurrent Queues and Stacks
Stacks, Queues, and Deques
Simulations and Reductions
CS510 - Portland State University
Combinatorial Topology and Distributed Computing
Barrier Synchronization
CS210- Lecture 5 Jun 9, 2005 Agenda Queues
Concurrent Queues and the ABA Problem
Stacks, Queues, and Deques
Presentation transcript:

Concurrent Queues Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming22 Another Fundamental Problem We told you about –Sets implemented by linked lists Next: queues Next: stacks

Art of Multiprocessor Programming33 Queue: Concurrency enq(x) y=deq() enq() and deq() work at different ends of the object tailhead

Art of Multiprocessor Programming44 Concurrency enq(x) Challenge: what if the queue is empty or full? y=deq() tail head

Art of Multiprocessor Programming55 Bounded Queue Sentinel head tail

Art of Multiprocessor Programming66 Bounded Queue head tail First actual item

Art of Multiprocessor Programming77 Bounded Queue head tail Lock out other deq() calls deqLock

Art of Multiprocessor Programming88 Bounded Queue head tail Lock out other enq() calls deqLock enqLock

Art of Multiprocessor Programming 99 Not Done Yet head tail deqLock enqLock Need to tell whether queue is full or empty

Art of Multiprocessor Programming10 Not Done Yet head tail deqLock enqLock Max size is 8 items size 1

Art of Multiprocessor Programming11 Not Done Yet head tail deqLock enqLock Incremented by enq() Decremented by deq() size 1

Art of Multiprocessor Programming12 Enqueuer head tail deqLock enqLock size 1 Lock enqLock

Art of Multiprocessor Programming13 Enqueuer head tail deqLock enqLock size 1 Read size OK

Art of Multiprocessor Programming14 Enqueuer head tail deqLock enqLock size 1 No need to lock tail

Art of Multiprocessor Programming15 Enqueuer head tail deqLock enqLock size 1 Enqueue Node

Art of Multiprocessor Programming16 Enqueuer head tail deqLock enqLock size 1 2 getAndincrement()

Art of Multiprocessor Programming17 Enqueuer head tail deqLock enqLock size 8 Release lock 2

Art of Multiprocessor Programming18 Enqueuer head tail deqLock enqLock size 2 If queue was empty, notify waiting dequeuers

Art of Multiprocessor Programming19 Unsuccesful Enqueuer head tail deqLock enqLock size 8 Uh-oh Read size …

Art of Multiprocessor Programming20 Dequeuer head tail deqLock enqLock size 2 Lock deqLock

Art of Multiprocessor Programming21 Dequeuer head tail deqLock enqLock size 2 Read sentinel’s next field OK

Art of Multiprocessor Programming22 Dequeuer head tail deqLock enqLock size 2 Read value

Art of Multiprocessor Programming23 Dequeuer head tail deqLock enqLock size 2 Make first Node new sentinel

Art of Multiprocessor Programming24 Dequeuer head tail deqLock enqLock size 1 Decrement size

Art of Multiprocessor Programming25 Dequeuer head tail deqLock enqLock size 1 Release deqLock

Art of Multiprocessor Programming26 Unsuccesful Dequeuer head tail deqLock enqLock size 0 Read sentinel’s next field uh-oh

Art of Multiprocessor Programming27 Bounded Queue public class BoundedQueue { ReentrantLock enqLock, deqLock; Condition notEmptyCondition, notFullCondition; AtomicInteger size; Node head; Node tail; int capacity; enqLock = new ReentrantLock(); notFullCondition = enqLock.newCondition(); deqLock = new ReentrantLock(); notEmptyCondition = deqLock.newCondition(); }

Art of Multiprocessor Programming28 Bounded Queue Fields public class BoundedQueue { ReentrantLock enqLock, deqLock; Condition notEmptyCondition, notFullCondition; AtomicInteger size; Node head; Node tail; int capacity; enqLock = new ReentrantLock(); notFullCondition = enqLock.newCondition(); deqLock = new ReentrantLock(); notEmptyCondition = deqLock.newCondition(); } Enq & deq locks

Art of Multiprocessor Programming29 Bounded Queue Fields public class BoundedQueue { ReentrantLock enqLock, deqLock; Condition notEmptyCondition, notFullCondition; AtomicInteger size; Node head; Node tail; int capacity; enqLock = new ReentrantLock(); notFullCondition = enqLock.newCondition(); deqLock = new ReentrantLock(); notEmptyCondition = deqLock.newCondition(); } Enq lock’s associated condition

Art of Multiprocessor Programming30 Bounded Queue Fields public class BoundedQueue { ReentrantLock enqLock, deqLock; Condition notEmptyCondition, notFullCondition; AtomicInteger size; Node head; Node tail; int capacity; enqLock = new ReentrantLock(); notFullCondition = enqLock.newCondition(); deqLock = new ReentrantLock(); notEmptyCondition = deqLock.newCondition(); } size: 0 to capacity

Art of Multiprocessor Programming31 Bounded Queue Fields public class BoundedQueue { ReentrantLock enqLock, deqLock; Condition notEmptyCondition, notFullCondition; AtomicInteger size; Node head; Node tail; int capacity; enqLock = new ReentrantLock(); notFullCondition = enqLock.newCondition(); deqLock = new ReentrantLock(); notEmptyCondition = deqLock.newCondition(); } Head and Tail

Art of Multiprocessor Programming32 Enq Method Part One public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == Capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … }

Art of Multiprocessor Programming33 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Enq Method Part One Lock and unlock enq lock

Art of Multiprocessor Programming34 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Enq Method Part One Wait while queue is full …

Art of Multiprocessor Programming35 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Enq Method Part One when await() returns, you might still fail the test !

Art of Multiprocessor Programming36 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Be Afraid After the loop: how do we know the queue won’t become full again?

Art of Multiprocessor Programming37 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Enq Method Part One Add new node

Art of Multiprocessor Programming38 public void enq(T x) { boolean mustWakeDequeuers = false; enqLock.lock(); try { while (size.get() == capacity) notFullCondition.await(); Node e = new Node(x); tail.next = e; tail = tail.next; if (size.getAndIncrement() == 0) mustWakeDequeuers = true; } finally { enqLock.unlock(); } … } Enq Method Part One If queue was empty, wake frustrated dequeuers

Art of Multiprocessor Programming39 Enq Method Part Deux public void enq(T x) { … if (mustWakeDequeuers) { deqLock.lock(); try { notEmptyCondition.signalAll(); } finally { deqLock.unlock(); }

Art of Multiprocessor Programming40 Enq Method Part Deux public void enq(T x) { … if (mustWakeDequeuers) { deqLock.lock(); try { notEmptyCondition.signalAll(); } finally { deqLock.unlock(); } Are there dequeuers to be signaled?

Art of Multiprocessor Programming41 public void enq(T x) { … if (mustWakeDequeuers) { deqLock.lock(); try { notEmptyCondition.signalAll(); } finally { deqLock.unlock(); } Enq Method Part Deux Lock and unlock deq lock

Art of Multiprocessor Programming42 public void enq(T x) { … if (mustWakeDequeuers) { deqLock.lock(); try { notEmptyCondition.signalAll(); } finally { deqLock.unlock(); } Enq Method Part Deux Signal dequeuers that queue is no longer empty

Art of Multiprocessor Programming43 The Enq() & Deq() Methods Share no locks –That’s good But do share an atomic counter –Accessed on every method call –That’s not so good Can we alleviate this bottleneck?

Art of Multiprocessor Programming44 Split the Counter The enq() method –Increments only –Cares only if value is capacity The deq() method –Decrements only –Cares only if value is zero

Art of Multiprocessor Programming45 Split Counter Enqueuer increments enqSize Dequeuer decrements deqSize When enqueuer runs out –Locks deqLock –computes size = enqSize - DeqSize Intermittent synchronization –Not with each method call –Need both locks! (careful …)

Art of Multiprocessor Programming46 A Lock-Free Queue Sentinel head tail

Art of Multiprocessor Programming47 Compare and Set CAS

Art of Multiprocessor Programming48 Enqueue head tail enq( )

Art of Multiprocessor Programming49 Logical Enqueue head tail CAS

Art of Multiprocessor Programming50 Physical Enqueue head tail CAS

Art of Multiprocessor Programming51 Enqueue These two steps are not atomic The tail field refers to either –Actual last Node (good) –Penultimate Node (not so good) Be prepared!

Art of Multiprocessor Programming52 Enqueue What do you do if you find –A trailing tail? Stop and help fix it –If tail node has non-null next field –CAS the queue’s tail field to tail.next

Art of Multiprocessor Programming53 When CASs Fail During logical enqueue –Abandon hope, restart –Still lock-free During physical enqueue –Ignore it

Art of Multiprocessor Programming 54

Art of Multiprocessor Programming55 Dequeuer head tail Read value

Art of Multiprocessor Programming56 Dequeuer head tail Make first Node new sentinel CAS

Art of Multiprocessor Programming 57

Art of Multiprocessor Programming58 Memory Reuse? What do we do with nodes after we dequeue them? Java: let garbage collector deal? Suppose there is no GC, or we prefer not to use it?

Art of Multiprocessor Programming59 Dequeuer head tail CAS Can recycle

Art of Multiprocessor Programming60 Simple Solution Each thread has a free list of unused queue nodes Allocate node: pop from list Free node: push onto list Deal with underflow somehow …

Art of Multiprocessor Programming61 Why Recycling is Hard Free pool headtail Want to redirect head from gray to red zzz… Head reference has value A Thread reads value A Head reference has value A Thread reads value A

Art of Multiprocessor Programming62 Both Nodes Reclaimed Free pool zzz headtail Head reference has value B Node A freed Head reference has value B Node A freed

Art of Multiprocessor Programming63 One Node Recycled Free pool Yawn! headtail Head reference has value A again Node A recycled and reinitialized Head reference has value A again Node A recycled and reinitialized

Art of Multiprocessor Programming64 Why Recycling is Hard Free pool CAS headtail OK, here I go! CAS succeeds because references match, even though reference’s meaning has changed CAS succeeds because references match, even though reference’s meaning has changed

Art of Multiprocessor Programming65 Recycle FAIL Free pool zOMG what went wrong? headtail

Art of Multiprocessor Programming66 The Dreaded ABA FAIL Is a result of CAS() semantics –I blame Sun, Intel, AMD, … Not with Load-Locked/Store-Conditional –Good for IBM?

Art of Multiprocessor Programming67 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? AtomicStampedReference class

Art of Multiprocessor Programming68 Atomic Stamped Reference AtomicStampedReference class –Java.util.concurrent.atomic package address S Stamp Reference Can get reference & stamp atomically

Art of Multiprocessor Programming 69

Art of Multiprocessor Programming70 This work is licensed under a Creative Commons Attribution- ShareAlike 2.5 License.Creative Commons Attribution- ShareAlike 2.5 License You are free: –to Share — to copy, distribute and transmit the work –to Remix — to adapt the work Under the following conditions: –Attribution. You must attribute the work to “The Art of Multiprocessor Programming” (but not in any way that suggests that the authors endorse you or your use of the work). –Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to – Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights.