![Page 1: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/1.jpg)
Concurrent Queues and Stacks
Companion slides for
The Art of Multiprocessor Programming
by Maurice Herlihy & Nir Shavit
![Page 2: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/2.jpg)
Art of Multiprocessor Programming 22
The Five-Fold Path
• Coarse-grained locking
• Fine-grained locking
• Optimistic synchronization
• Lazy synchronization
• Lock-free synchronization
![Page 3: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/3.jpg)
Art of Multiprocessor Programming 33
Another Fundamental Problem
• We told you about
– Sets implemented by linked lists
– Hash Tables
• Next: queues
• Next: stacks
![Page 4: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/4.jpg)
Art of Multiprocessor Programming 44
Queues & Stacks
• pool of items
![Page 5: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/5.jpg)
Art of Multiprocessor Programming 55
Queues
deq()/enq( )
Total order
First in
First out
![Page 6: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/6.jpg)
Art of Multiprocessor Programming 66
Stacks
pop()/
push( )
Total order
Last in
First out
![Page 7: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/7.jpg)
Art of Multiprocessor Programming 77
Bounded
• Fixed capacity
• Good when resources an issue
![Page 8: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/8.jpg)
Art of Multiprocessor Programming 88
Unbounded
• Unlimited capacity
• Often more convenient
![Page 9: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/9.jpg)
Art of Multiprocessor Programming 9
Blocking
zzz …
Block on attempt to remove from empty stack or queue
![Page 10: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/10.jpg)
Art of Multiprocessor Programming 10
Blocking
zzz …
Block on attempt to add to full bounded stack or queue
![Page 11: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/11.jpg)
Art of Multiprocessor Programming 11
Non-Blocking
Ouch!
Throw exception on attempt to remove from empty stack or queue
![Page 12: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/12.jpg)
Art of Multiprocessor Programming 1212
This Lecture
• Queue
– Bounded, blocking, lock-based
– Unbounded, non-blocking, lock-free
• Stack
– Unbounded, non-blocking lock-free
– Elimination-backoff algorithm
![Page 13: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/13.jpg)
Art of Multiprocessor Programming 1313
Queue: Concurrency
enq(x) y=deq()
enq() and deq()
work at different
ends of the object
tail head
![Page 14: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/14.jpg)
Art of Multiprocessor Programming 1414
Concurrency
enq(x)
Challenge: what if
the queue is empty
or full?
y=deq()
![Page 15: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/15.jpg)
Art of Multiprocessor Programming 1515
Bounded Queue
Sentinel
head
tail
![Page 16: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/16.jpg)
Art of Multiprocessor Programming 1616
Bounded Queue
head
tail
First actual item
![Page 17: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/17.jpg)
Art of Multiprocessor Programming 1717
Bounded Queue
head
tail
Lock out other
deq() calls
deqLock
![Page 18: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/18.jpg)
Art of Multiprocessor Programming 1818
Bounded Queue
head
tail
Lock out other
enq() calls
deqLock
enqLock
![Page 19: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/19.jpg)
Art of Multiprocessor Programming 1919
Not Done Yet
head
tail
deqLock
enqLock
Need to tell whether
queue is full or
empty
![Page 20: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/20.jpg)
Art of Multiprocessor Programming 2020
Not Done Yet
head
tail
deqLock
enqLock
Max size is 8 items
size
1
![Page 21: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/21.jpg)
Art of Multiprocessor Programming 2121
Not Done Yet
head
tail
deqLock
enqLock
Incremented by enq()
Decremented by deq()
size
1
![Page 22: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/22.jpg)
Art of Multiprocessor Programming 2222
Enqueuer
1
Lock enqLock
head
tail
deqLock
enqLock
size
![Page 23: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/23.jpg)
Art of Multiprocessor Programming 2323
Enqueuer
1
Read size
OK
head
tail
deqLock
enqLock
size
![Page 24: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/24.jpg)
Art of Multiprocessor Programming 2424
Enqueuer
1
No need to
lock tail
head
tail
deqLock
enqLock
size
![Page 25: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/25.jpg)
Art of Multiprocessor Programming 2525
Enqueuer
1
Enqueue Node
head
tail
deqLock
enqLock
size
![Page 26: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/26.jpg)
Art of Multiprocessor Programming 2626
Enqueuer
size
12
getAndincrement()
head
tail
deqLock
enqLock
![Page 27: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/27.jpg)
Art of Multiprocessor Programming 2727
Enqueuer
8Release lock
2
head
tail
deqLock
enqLock
size
![Page 28: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/28.jpg)
Art of Multiprocessor Programming 2828
Enqueuer
2
If queue was empty,
notify waiting dequeuers
head
tail
deqLock
enqLock
size
![Page 29: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/29.jpg)
Art of Multiprocessor Programming 2929
Unsuccesful Enqueuer
8
Uh-oh
Read size
…head
tail
deqLock
enqLock
size
![Page 30: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/30.jpg)
Art of Multiprocessor Programming 3030
Dequeuer
2
Lock deqLock
head
tail
deqLock
enqLock
size
![Page 31: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/31.jpg)
Art of Multiprocessor Programming 3131
Dequeuer
2
Read sentinel’s
next field
OK
head
tail
deqLock
enqLock
size
![Page 32: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/32.jpg)
Art of Multiprocessor Programming 3232
Dequeuer
siz
2
Read value
head
tail
deqLock
enqLock
size
![Page 33: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/33.jpg)
Art of Multiprocessor Programming 3333
Dequeuer
2
Make first Node
new sentinel
head
tail
deqLock
enqLock
size
![Page 34: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/34.jpg)
Art of Multiprocessor Programming 3434
Dequeuer
1
Decrement
size
head
tail
deqLock
enqLock
size
![Page 35: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/35.jpg)
Art of Multiprocessor Programming 3535
Dequeuer
1Release
deqLock
head
tail
deqLock
enqLock
size
![Page 36: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/36.jpg)
Art of Multiprocessor Programming 3636
Unsuccesful Dequeuer
0
Read sentinel’s
next field
uh-oh
head
tail
deqLock
enqLock
size
![Page 37: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/37.jpg)
Art of Multiprocessor Programming 3737
Bounded Queue
public class BoundedQueue<T> {
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();
}
![Page 38: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/38.jpg)
Art of Multiprocessor Programming 3838
Bounded Queue
public class BoundedQueue<T> {
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
![Page 39: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/39.jpg)
Art of Multiprocessor Programming 39
(push)
![Page 40: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/40.jpg)
Art of Multiprocessor Programming 4040
Digression: Monitor Locks
• Java synchronized objects and ReentrantLocks are monitors
• Allow blocking on a condition rather than spinning
• Threads: – acquire and release lock
– wait on a condition
![Page 41: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/41.jpg)
Art of Multiprocessor Programming 4141
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit);
Condition newCondition();
void unlock;
}
The Java Lock Interface
Acquire lock
![Page 42: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/42.jpg)
Art of Multiprocessor Programming 4242
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit);
Condition newCondition();
void unlock;
}
The Java Lock Interface
Release lock
![Page 43: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/43.jpg)
Art of Multiprocessor Programming 4343
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit);
Condition newCondition();
void unlock;
}
The Java Lock Interface
Try for lock, but not too hard
![Page 44: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/44.jpg)
Art of Multiprocessor Programming 4444
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit);
Condition newCondition();
void unlock;
}
The Java Lock Interface
Create condition to wait on
![Page 45: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/45.jpg)
Art of Multiprocessor Programming 4545
The Java Lock Interface
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit);
Condition newCondition();
void unlock;
}
Never mind what this method does
![Page 46: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/46.jpg)
Art of Multiprocessor Programming 4646
Lock Conditions
public interface Condition {
void await();
boolean await(long time, TimeUnit unit);
…
void signal();
void signalAll();
}
![Page 47: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/47.jpg)
Art of Multiprocessor Programming 4747
public interface Condition {
void await();
boolean await(long time, TimeUnit unit);
…
void signal();
void signalAll();
}
Lock Conditions
Release lock and
wait on condition
![Page 48: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/48.jpg)
Art of Multiprocessor Programming 4848
public interface Condition {
void await();
boolean await(long time, TimeUnit unit);
…
void signal();
void signalAll();
}
Lock Conditions
Wake up one waiting thread
![Page 49: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/49.jpg)
Art of Multiprocessor Programming 4949
public interface Condition {
void await();
boolean await(long time, TimeUnit unit);
…
void signal();
void signalAll();
}
Lock Conditions
Wake up all waiting threads
![Page 50: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/50.jpg)
Art of Multiprocessor Programming 5050
Await
• Releases lock associated with q
• Sleeps (gives up processor)
• Awakens (resumes running)
• Reacquires lock & returns
q.await()
![Page 51: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/51.jpg)
Art of Multiprocessor Programming 5151
Signal
• Awakens one waiting thread
– Which will reacquire lock
q.signal();
![Page 52: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/52.jpg)
Art of Multiprocessor Programming 5252
Signal All
• Awakens all waiting threads
– Which will each reacquire lock
q.signalAll();
![Page 53: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/53.jpg)
Art of Multiprocessor Programming 5353
A Monitor Lock
Cri
tical S
ecti
on
waiting room
lock()
unlock()
![Page 54: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/54.jpg)
Art of Multiprocessor Programming 5454
Unsuccessful Deq
Cri
tical S
ecti
on
waiting room
lock()
await()
deq()
Oh no,
empty!
![Page 55: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/55.jpg)
Art of Multiprocessor Programming 5555
Another One
Cri
tical S
ecti
on
waiting room
lock()
await()
deq()
Oh no,
empty!
![Page 56: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/56.jpg)
Art of Multiprocessor Programming 5656
Enqueuer to the Rescue
Cri
tical S
ecti
on
waiting room
lock()
signalAll()enq( )
unlock()
Yawn!Yawn!
![Page 57: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/57.jpg)
Art of Multiprocessor Programming 5757
Yawn!
Monitor Signalling
Cri
tical S
ecti
on
waiting room
Yawn!
Awakened thread
might still lose lock to
outside contender…
![Page 58: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/58.jpg)
Art of Multiprocessor Programming 5858
Dequeuers Signalled
Cri
tical S
ecti
on
waiting room
Found it
Yawn!
![Page 59: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/59.jpg)
Art of Multiprocessor Programming 5959
Yawn!
Dequeuers Signaled
Cri
tical S
ecti
on
waiting room
Still empty!
![Page 60: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/60.jpg)
Art of Multiprocessor Programming 6060
Dollar Short + Day Late
Cri
tical S
ecti
on
waiting room
![Page 61: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/61.jpg)
Art of Multiprocessor Programming 6161
public class Queue<T> {
int head = 0, tail = 0;
T[QSIZE] items;
public synchronized T deq() {
while (tail – head == 0)
wait();
T result = items[head % QSIZE]; head++;
notifyAll();
return result;
}
…
}}
Java Synchronized Methods
![Page 62: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/62.jpg)
Art of Multiprocessor Programming 6262
public class Queue<T> {
int head = 0, tail = 0;
T[QSIZE] items;
public synchronized T deq() {
while (tail – head == 0)
wait();
T result = items[head % QSIZE]; head++;
notifyAll();
return result;
}
…
}}
Java Synchronized Methods
Each object has an implicit
lock with an implicit condition
![Page 63: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/63.jpg)
Art of Multiprocessor Programming 6363
public class Queue<T> {
int head = 0, tail = 0;
T[QSIZE] items;
public synchronized T deq() {
while (tail – head == 0)
wait();
T result = items[head % QSIZE]; head++;
notifyAll();
return result;
}
…
}}
Java Synchronized Methods
Lock on entry,
unlock on return
![Page 64: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/64.jpg)
Art of Multiprocessor Programming 6464
public class Queue<T> {
int head = 0, tail = 0;
T[QSIZE] items;
public synchronized T deq() {
while (tail – head == 0)
wait();
T result = items[head % QSIZE]; head++;
this.notifyAll();
return result;
}
…
}}
Java Synchronized Methods
Wait on implicit
condition
![Page 65: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/65.jpg)
Art of Multiprocessor Programming 6565
public class Queue<T> {
int head = 0, tail = 0;
T[QSIZE] items;
public synchronized T deq() {
while (tail – head == 0)
this.wait();
T result = items[head % QSIZE]; head++;
notifyAll();
return result;
}
…
}}
Java Synchronized Methods
Signal all threads waiting
on condition
![Page 66: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/66.jpg)
Art of Multiprocessor Programming 6666
(Pop!) The Bounded Queue
public class BoundedQueue<T> {
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();
}
![Page 67: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/67.jpg)
Art of Multiprocessor Programming 6767
Bounded Queue Fields
public class BoundedQueue<T> {
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
![Page 68: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/68.jpg)
Art of Multiprocessor Programming 6868
Bounded Queue Fields
public class BoundedQueue<T> {
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
![Page 69: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/69.jpg)
Art of Multiprocessor Programming 6969
Bounded Queue Fields
public class BoundedQueue<T> {
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
![Page 70: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/70.jpg)
Art of Multiprocessor Programming 7070
Bounded Queue Fields
public class BoundedQueue<T> {
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
![Page 71: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/71.jpg)
Art of Multiprocessor Programming 7171
Enq Method Part Onepublic 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();
}
…
}
![Page 72: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/72.jpg)
Art of Multiprocessor Programming 7272
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
![Page 73: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/73.jpg)
Art of Multiprocessor Programming 7373
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 …
![Page 74: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/74.jpg)
Art of Multiprocessor Programming 7474
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 !
![Page 75: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/75.jpg)
Art of Multiprocessor Programming 7575
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?
![Page 76: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/76.jpg)
Art of Multiprocessor Programming 7676
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
![Page 77: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/77.jpg)
Art of Multiprocessor Programming 7777
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
![Page 78: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/78.jpg)
Art of Multiprocessor Programming 7878
Beware Lost Wake-Ups
Cri
tical S
ecti
on
waiting room
lock()
Queue empty
so signal ()
enq( )
unlock()
Yawn!
![Page 79: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/79.jpg)
Art of Multiprocessor Programming 7979
Lost Wake-Up
Cri
tical S
ecti
on
waiting room
lock()
enq( )
unlock()
Yawn!
Queue not
empty so no
need to signal
![Page 80: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/80.jpg)
Art of Multiprocessor Programming 8080
Lost Wake-Up
Cri
tical S
ecti
on
waiting room
Yawn!
![Page 81: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/81.jpg)
Art of Multiprocessor Programming 8181
Lost Wake-Up
Cri
tical S
ecti
on
waiting room
Found it
![Page 82: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/82.jpg)
Art of Multiprocessor Programming 8282
What’s Wrong Here?
Cri
tical S
ecti
on
waiting room
Still waiting ….!
![Page 83: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/83.jpg)
Art of Multiprocessor Programming 83
Solution to Lost Wakeup
• Always use
– signalAll() and notifyAll()
• Not
– signal() and notify()
83
![Page 84: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/84.jpg)
Art of Multiprocessor Programming 84
(pop)
![Page 85: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/85.jpg)
Art of Multiprocessor Programming 8585
Enq Method Part Deux
public void enq(T x) {
…
if (mustWakeDequeuers) {
deqLock.lock();
try {
notEmptyCondition.signalAll();
} finally {
deqLock.unlock();
}
}
}
![Page 86: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/86.jpg)
Art of Multiprocessor Programming 8686
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?
![Page 87: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/87.jpg)
Art of Multiprocessor Programming 8787
public void enq(T x) {
…
if (mustWakeDequeuers) {
deqLock.lock();
try {
notEmptyCondition.signalAll();
} finally {
deqLock.unlock();
}
}
}
Enq Method Part Deux
Lock and
unlock deq lock
![Page 88: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/88.jpg)
Art of Multiprocessor Programming 8888
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
![Page 89: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/89.jpg)
Art of Multiprocessor Programming 8989
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?
![Page 90: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/90.jpg)
Art of Multiprocessor Programming 9090
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
![Page 91: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/91.jpg)
Art of Multiprocessor Programming 9191
Split Counter
• Enqueuer increments enqSize
• Dequeuer increments deqSize
• When enqueuer hits capacity– Locks deqLock
– Sets size = enqSize - DeqSize
• Intermittent synchronization
– Not with each method call
– Need both locks! (careful …)
![Page 92: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/92.jpg)
Art of Multiprocessor Programming 9292
A Lock-Free Queue
Sentinel
head
tail
![Page 93: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/93.jpg)
Art of Multiprocessor Programming 9393
Compare and Set
CAS
![Page 94: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/94.jpg)
Art of Multiprocessor Programming 9494
Enqueue
head
tail
enq( )
![Page 95: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/95.jpg)
Art of Multiprocessor Programming 9595
Enqueue
head
tail
![Page 96: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/96.jpg)
Art of Multiprocessor Programming 9696
Logical Enqueue
head
tail
CAS
![Page 97: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/97.jpg)
Art of Multiprocessor Programming 9797
Physical Enqueue
head
tailCAS
![Page 98: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/98.jpg)
Art of Multiprocessor Programming 9898
Enqueue
• These two steps are not atomic
• The tail field refers to either
– Actual last Node (good)
– Penultimate Node (not so good)
• Be prepared!
![Page 99: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/99.jpg)
Art of Multiprocessor Programming 9999
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
• As in the universal construction
![Page 100: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/100.jpg)
Art of Multiprocessor Programming 100100
When CASs Fail
• During logical enqueue
– Abandon hope, restart
– Still lock-free (why?)
• During physical enqueue
– Ignore it (why?)
![Page 101: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/101.jpg)
Art of Multiprocessor Programming 101101
Dequeuer
head
tail
Read value
![Page 102: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/102.jpg)
Art of Multiprocessor Programming 102102
Dequeuer
head
tail
Make first Node
new sentinel
CAS
![Page 103: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/103.jpg)
Art of Multiprocessor Programming 103103
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?
![Page 104: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/104.jpg)
Art of Multiprocessor Programming 104104
Dequeuer
head
tail
CAS
Can recycle
![Page 105: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/105.jpg)
Art of Multiprocessor Programming 105105
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 …
![Page 106: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/106.jpg)
Art of Multiprocessor Programming 106106
Why Recycling is Hard
Free pool
head tail
Want to
redirect
head from
gray to red
zzz…
![Page 107: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/107.jpg)
Art of Multiprocessor Programming 107107
Both Nodes Reclaimed
Free pool
zzz
head tail
![Page 108: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/108.jpg)
Art of Multiprocessor Programming 108108
One Node Recycled
Free pool
Yawn!
head tail
![Page 109: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/109.jpg)
Art of Multiprocessor Programming 109109
Why Recycling is Hard
Free pool
CAS
head tail
OK, here
I go!
![Page 110: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/110.jpg)
Art of Multiprocessor Programming 110110
Recycle FAIL
Free pool
zOMG what went wrong?
head tail
![Page 111: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/111.jpg)
Art of Multiprocessor Programming 111111
The Dreaded ABA Problemhead tail
Head reference has value A
Thread reads value A
![Page 112: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/112.jpg)
Art of Multiprocessor Programming 112112
Dreaded ABA continued
zzz
head tail
Head reference has value B
Node A freed
![Page 113: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/113.jpg)
Art of Multiprocessor Programming 113113
Dreaded ABA continued
Yawn!
head tail
Head reference has value A again
Node A recycled and reinitialized
![Page 114: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/114.jpg)
Art of Multiprocessor Programming 114114
Dreaded ABA continued
CAS
head tail
CAS succeeds because references match,
even though reference’s meaning has changed
![Page 115: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/115.jpg)
Art of Multiprocessor Programming 115115
The Dreaded ABA FAIL
• Is a result of CAS() semantics
– Oracle, Intel, AMD, …
• Not with Load-Locked/Store-Conditional
– IBM …
![Page 116: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/116.jpg)
Art of Multiprocessor Programming 116116
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
![Page 117: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/117.jpg)
Art of Multiprocessor Programming 117117
Atomic Stamped Reference
• AtomicStampedReference class
– Java.util.concurrent.atomic package
address S
Stamp
Reference
Can get reference & stamp atomically
![Page 118: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/118.jpg)
Art of Multiprocessor Programming 118118
Concurrent Stack
• Methods
– push(x)
– pop()
• Last-in, First-out (LIFO) order
• Lock-Free!
![Page 119: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/119.jpg)
Art of Multiprocessor Programming 119119
Empty Stack
Top
![Page 120: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/120.jpg)
Art of Multiprocessor Programming 120120
Push
Top
![Page 121: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/121.jpg)
Art of Multiprocessor Programming 121121
Push
TopCAS
![Page 122: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/122.jpg)
Art of Multiprocessor Programming 122122
Push
Top
![Page 123: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/123.jpg)
Art of Multiprocessor Programming 123123
Push
Top
![Page 124: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/124.jpg)
Art of Multiprocessor Programming 124124
Push
Top
![Page 125: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/125.jpg)
Art of Multiprocessor Programming 125125
Push
TopCAS
![Page 126: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/126.jpg)
Art of Multiprocessor Programming 126126
Push
Top
![Page 127: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/127.jpg)
Art of Multiprocessor Programming 127127
Pop
Top
![Page 128: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/128.jpg)
Art of Multiprocessor Programming 128128
Pop
TopCAS
![Page 129: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/129.jpg)
Art of Multiprocessor Programming 129129
Pop
TopCAS
mine!
![Page 130: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/130.jpg)
Art of Multiprocessor Programming 130130
Pop
TopCAS
![Page 131: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/131.jpg)
Art of Multiprocessor Programming 131131
Pop
Top
![Page 132: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/132.jpg)
Art of Multiprocessor Programming 132132
public class LockFreeStack {
private AtomicReference top =
new AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff();
}}
Lock-free Stack
![Page 133: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/133.jpg)
Art of Multiprocessor Programming 133133
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public Boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
tryPush attempts to push a node
![Page 134: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/134.jpg)
Art of Multiprocessor Programming 134134
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
Read top value
![Page 135: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/135.jpg)
Art of Multiprocessor Programming 135135
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
current top will be new node’s successor
![Page 136: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/136.jpg)
Art of Multiprocessor Programming 136136
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
Try to swing top, return success or failure
![Page 137: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/137.jpg)
Art of Multiprocessor Programming 137137
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
Push calls tryPush
![Page 138: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/138.jpg)
Art of Multiprocessor Programming 138138
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
Create new node
![Page 139: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/139.jpg)
Art of Multiprocessor Programming 139139
public class LockFreeStack {
private AtomicReference top = new
AtomicReference(null);
public boolean tryPush(Node node){
Node oldTop = top.get();
node.next = oldTop;
return(top.compareAndSet(oldTop, node))
}
public void push(T value) {
Node node = new Node(value);
while (true) {
if (tryPush(node)) {
return;
} else backoff.backoff()
}}
Lock-free Stack
If tryPush() fails,
back off before retrying
![Page 140: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/140.jpg)
Art of Multiprocessor Programming 140140
Lock-free Stack
• Good
– No locking
• Bad
– Without GC, fear ABA
– Without backoff, huge contention at top
– In any case, no parallelism
![Page 141: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/141.jpg)
Art of Multiprocessor Programming 141141
Big Question
• Are stacks inherently sequential?
• Reasons why
– Every pop() call fights for top item
• Reasons why not
– Stay tuned …
![Page 142: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/142.jpg)
Art of Multiprocessor Programming 142142
Elimination-Backoff Stack
• How to
– “turn contention into parallelism”
• Replace familiar
– exponential backoff
• With alternative
– elimination-backoff
![Page 143: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/143.jpg)
Art of Multiprocessor Programming 143143
Observation
Push( )
Pop()
linearizable stack
After an equal number
of pushes and pops,
stack stays the sameYes!
![Page 144: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/144.jpg)
Art of Multiprocessor Programming 144144
Idea: Elimination Array
Push( )
Pop()
stack
Pick at
random
Pick at
random Elimination
Array
![Page 145: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/145.jpg)
Art of Multiprocessor Programming 145145
Push Collides With Pop
Push( )
Pop()
stack
continue
continue
No need to
access stack Yes!
![Page 146: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/146.jpg)
Art of Multiprocessor Programming 146146
No Collision
Push( )
Pop()
stack
If no collision,
access stack
If pushes collide or
pops collide
access stack
![Page 147: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/147.jpg)
Art of Multiprocessor Programming 147147
Elimination-Backoff Stack
• Lock-free stack + elimination array
• Access Lock-free stack,
– If uncontended, apply operation
– if contended, back off to elimination array
and attempt elimination
![Page 148: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/148.jpg)
Art of Multiprocessor Programming 148148
Elimination-Backoff Stack
Push( )
Pop()TopCAS
If CAS fails, back off
![Page 149: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/149.jpg)
Art of Multiprocessor Programming 149149
Dynamic Range and Delay
Push( )
Pick random range and
max waiting time based
on level of contention
encountered
![Page 150: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/150.jpg)
50-50, Random Slots
0
20000
40000
60000
80000
100000
120000
2 4 8 121 62 4 324 04 85 66 4
Threads
ops/ msec Exchanger
Treiber
![Page 151: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/151.jpg)
Asymmetric Rendevous
pop1()pop2()
Push( )
Pops find first vacant slot
and spin. Pushes hunt for
pops.
15 94 26head:
![Page 152: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/152.jpg)
Asymmetric vs. Symmetric
0
20000
40000
60000
80000
100000
120000
2 4 8 12 16 24 32 40 48 56 64
op
s/m
se
c
Threads
50% Push/50% Pop/Random ids
Exchanger
Rendezvous
Treiber
![Page 153: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/153.jpg)
(a) Instructions/op
0
100
200
300
400
500
600
2 4 8 12 16 24 32 40 48 56 64
Threads
instr
ucti
on
s/o
p
Exchanger
Rendezvous
Treiber
(b) Cache misses/op
0
5
10
15
20
25
30
2 4 8 12 16 24 32 40 48 56 64
Threads
instr
ucti
on
s/o
p
Exchanger
Rendezvous
Treiber
(c) CAS/op
0
5
10
15
20
25
30
2 4 8 12 16 24 32 40 48 56 64
Threads
instr
ucti
on
s/o
p
Exchanger
Rendezvous
Treiber
50% Push/50% Pop/Random ids
0
20000
40000
60000
80000
100000
120000
2 4 8 12 16 24 32 40 48 56 64
Threads
op
s/m
sec
Exchanger
Rendezvous
Treiber
![Page 154: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/154.jpg)
50% Push/50% Pop
0
20000
40000
60000
80000
100000
120000
140000
2 4 8 12 16 24 32 40 48 56 64
Threads
op
s/m
se
c
Rendezvous (random ids)
Rendezvous(backoff,
random ids)
Rendezvous (seq ids)
Rendezvous(backoff, seq
ids)
Effect of Backoff and Slot Choice
![Page 155: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/155.jpg)
Effect of Slot Choice
Random choice Sequential choice
Darker shades mean more exchanges
![Page 156: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/156.jpg)
110
115
120
125
130
135
140
145
150
2 4 8 12 16 24 32 40 48 56 64
ins
tru
cti
on
s/o
p
Threads
Rendezvous instruction count:
sequential vs. random ids
Push (random ids) Pop (random ids)
Push (seq ids) Pop (seq ids)
Rendezvous array probes:
sequential vs. random ids
0
2
4
6
8
10
2 4 8 12 16 24 32 40 48 56 64
Threads
# p
ro
bes
Push (random ids) Push (seq ids)
Pop (random ids) Pop (seq ids)
Effect of Slot Choice
Rendezvous Pop spin iterations:
sequential vs. random ids
0
2
4
6
8
1 2 3 4 5 6 7 8 9 10 11
Threads
# s
pin
s
Pop (random ids) Pop (seq ids)
![Page 157: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/157.jpg)
Art of Multiprocessor Programming 157157
Linearizability
• Un-eliminated calls
– linearized as before
• Eliminated calls:
– linearize pop() immediately after
matching push()
• Combination is a linearizable stack
![Page 158: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/158.jpg)
Art of Multiprocessor Programming 158158
Un-Eliminated Linearizability
push(v1)
timetime
push(v1)
pop(v1)pop(v1)
![Page 159: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/159.jpg)
Art of Multiprocessor Programming 159159
Eliminated Linearizability
pop(v2)push(v1)
push(v2)
timetime
push(v2)
pop(v2)push(v1)
pop(v1)
Collision
Point
Red calls are
eliminated
pop(v1)
![Page 160: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/160.jpg)
Art of Multiprocessor Programming 160160
Backoff Has Dual Effect
• Elimination introduces parallelism
• Backoff to array cuts contention on lock-
free stack
• Elimination in array cuts down number
of threads accessing lock-free stack
![Page 161: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/161.jpg)
Art of Multiprocessor Programming 161161
public class EliminationArray {
private static final int duration = ...;
private static final int timeUnit = ...;
Exchanger<T>[] exchanger;
public EliminationArray(int capacity) {
exchanger = new Exchanger[capacity];
for (int i = 0; i < capacity; i++)
exchanger[i] = new Exchanger<T>();
…
}
…
}
Elimination Array
![Page 162: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/162.jpg)
Art of Multiprocessor Programming 162162
public class EliminationArray {
private static final int duration = ...;
private static final int timeUnit = ...;
Exchanger<T>[] exchanger;
public EliminationArray(int capacity) {
exchanger = new Exchanger[capacity];
for (int i = 0; i < capacity; i++)
exchanger[i] = new Exchanger<T>();
…
}
…
}
Elimination Array
An array of Exchangers
![Page 163: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/163.jpg)
Art of Multiprocessor Programming 163163
public class Exchanger<T> {
AtomicStampedReference<T> slot
= new AtomicStampedReference<T>(null, 0);
Digression: A Lock-Free
Exchanger
![Page 164: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/164.jpg)
Art of Multiprocessor Programming 164164
public class Exchanger<T> {
AtomicStampedReference<T> slot
= new AtomicStampedReference<T>(null, 0);
A Lock-Free Exchanger
Atomically modifiable
reference + status
![Page 165: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/165.jpg)
Art of Multiprocessor Programming 165165
Atomic Stamped Reference
• AtomicStampedReference class
– Java.util.concurrent.atomic package
• In C or C++:
address Sreference
stamp
![Page 166: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/166.jpg)
Art of Multiprocessor Programming 166166
Extracting Reference & Stamp
public T get(int[] stampHolder);
![Page 167: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/167.jpg)
Art of Multiprocessor Programming 167167
Extracting Reference & Stamp
public T get(int[] stampHolder);
Returns reference to
object of type T
Returns stamp at
array index 0!
![Page 168: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/168.jpg)
Art of Multiprocessor Programming 168168
Exchanger Status
enum Status {EMPTY, WAITING, BUSY};
![Page 169: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/169.jpg)
Art of Multiprocessor Programming 169169
Exchanger Status
enum Status {EMPTY, WAITING, BUSY};
Nothing yet
![Page 170: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/170.jpg)
enum Status {EMPTY, WAITING, BUSY};
Art of Multiprocessor Programming 170170
Exchange Status
Nothing yet
One thread is waiting
for rendez-vous
![Page 171: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/171.jpg)
Art of Multiprocessor Programming 171171
Exchange Status
enum Status {EMPTY, WAITING, BUSY};
Nothing yet
One thread is waiting
for rendez-vous
Other threads busy
with rendez-vous
![Page 172: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/172.jpg)
Art of Multiprocessor Programming 172172
public T Exchange(T myItem, long nanos)
throws TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {EMPTY};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: … // slot is free
case WAITING: … // someone waiting for me
case BUSY: … // others exchanging
}
}
The Exchange
![Page 173: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/173.jpg)
Art of Multiprocessor Programming 173173
public T Exchange(T myItem, long nanos)
throws TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {EMPTY};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: … // slot is free
case WAITING: … // someone waiting for me
case BUSY: … // others exchanging
}
}
The Exchange
Item and timeout
![Page 174: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/174.jpg)
Art of Multiprocessor Programming 174174
public T Exchange(T myItem, long nanos)
throws TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {EMPTY};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: … // slot is free
case WAITING: … // someone waiting for me
case BUSY: … // others exchanging
}
}
The Exchange
Array holds status
![Page 175: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/175.jpg)
Art of Multiprocessor Programming 175175
public T Exchange(T myItem, long nanos) throws
TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {0};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: // slot is free
case WAITING: // someone waiting for me
case BUSY: // others exchanging
}
}}
The Exchange
Loop until timeout
![Page 176: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/176.jpg)
Art of Multiprocessor Programming 176176
public T Exchange(T myItem, long nanos) throws
TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {0};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: // slot is free
case WAITING: // someone waiting for me
case BUSY: // others exchanging
}
}}
The Exchange
Get other’s item and status
![Page 177: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/177.jpg)
Art of Multiprocessor Programming 177177
public T Exchange(T myItem, long nanos) throws
TimeoutException {
long timeBound = System.nanoTime() + nanos;
int[] stampHolder = {0};
while (true) {
if (System.nanoTime() > timeBound)
throw new TimeoutException();
T herItem = slot.get(stampHolder);
int stamp = stampHolder[0];
switch(stamp) {
case EMPTY: … // slot is free
case WAITING: … // someone waiting for me
case BUSY: … // others exchanging
}
}}
The Exchange
An Exchanger has three possible states
![Page 178: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/178.jpg)
Art of Multiprocessor Programming 178178
Lock-free Exchanger
EMPTY
![Page 179: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/179.jpg)
Art of Multiprocessor Programming 179179
EMPTY
Lock-free Exchanger
CAS
![Page 180: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/180.jpg)
Art of Multiprocessor Programming 180180
WAITING
Lock-free Exchanger
![Page 181: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/181.jpg)
Art of Multiprocessor Programming 181181
Lock-free Exchanger
In search of
partner …
WAITING
![Page 182: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/182.jpg)
Art of Multiprocessor Programming 182182
WAITING
Lock-free Exchanger
Slot
Still waiting …
Try to exchange
item and set
status to BUSY
CAS
![Page 183: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/183.jpg)
Art of Multiprocessor Programming 183183
BUSY
Lock-free Exchanger
Slot
Partner showed
up, take item and
reset to EMPTY
item status
![Page 184: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/184.jpg)
Art of Multiprocessor Programming 184184
EMPTYBUSY
Lock-free Exchanger
Slot
item status
Partner showed
up, take item and
reset to EMPTY
![Page 185: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/185.jpg)
Art of Multiprocessor Programming 185185
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
![Page 186: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/186.jpg)
Art of Multiprocessor Programming 186186
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
Try to insert myItem and
change state to WAITING
![Page 187: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/187.jpg)
Art of Multiprocessor Programming 187187
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
Spin until either
myItem is taken or timeout
![Page 188: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/188.jpg)
Art of Multiprocessor Programming 188188
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
myItem was taken,
so return herItem
that was put in its place
![Page 189: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/189.jpg)
Art of Multiprocessor Programming 189189
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
Otherwise we ran out of time,
try to reset status to EMPTY
and time out
![Page 190: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/190.jpg)
Art of Multiprocessor Programming 190Art of Multiprocessor
Programming© Herlihy-Shavit
2007
190
case EMPTY: // slot is free
if (slot.compareAndSet(herItem, myItem, WAITING,
BUSY)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.compareAndSet(myItem, null, WAITING,
EMPTY)){throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
If reset failed,
someone showed up after all,
so take that item
![Page 191: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/191.jpg)
Art of Multiprocessor Programming 191191
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
Clear slot and take that item
![Page 192: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/192.jpg)
Art of Multiprocessor Programming 192192
case EMPTY: // slot is free
if (slot.CAS(herItem, myItem, EMPTY, WAITING)) {
while (System.nanoTime() < timeBound){
herItem = slot.get(stampHolder);
if (stampHolder[0] == BUSY) {
slot.set(null, EMPTY);
return herItem;
}}
if (slot.CAS(myItem, null, WAITING, EMPTY)){
throw new TimeoutException();
} else {
herItem = slot.get(stampHolder);
slot.set(null, EMPTY);
return herItem;
}
} break;
Exchanger State EMPTY
If initial CAS failed,
then someone else changed status
from EMPTY to WAITING,
so retry from start
![Page 193: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/193.jpg)
Art of Multiprocessor Programming 193193
case WAITING: // someone waiting for me
if (slot.CAS(herItem, myItem, WAITING, BUSY))
return herItem;
break;
case BUSY: // others in middle of exchanging
break;
default: // impossible
break;
}
}
}
}
States WAITING and BUSY
![Page 194: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/194.jpg)
Art of Multiprocessor Programming 194194
case WAITING: // someone waiting for me
if (slot.CAS(herItem, myItem, WAITING, BUSY))
return herItem;
break;
case BUSY: // others in middle of exchanging
break;
default: // impossible
break;
}
}
}
}
States WAITING and BUSY
someone is waiting to exchange,
so try to CAS my item in
and change state to BUSY
![Page 195: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/195.jpg)
Art of Multiprocessor Programming 195195
case WAITING: // someone waiting for me
if (slot.CAS(herItem, myItem, WAITING, BUSY))
return herItem;
break;
case BUSY: // others in middle of exchanging
break;
default: // impossible
break;
}
}
}
}
States WAITING and BUSY
If successful, return other’s item,
otherwise someone else took it,
so try again from start
![Page 196: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/196.jpg)
Art of Multiprocessor Programming 196196
case WAITING: // someone waiting for me
if (slot.CAS(herItem, myItem, WAITING, BUSY))
return herItem;
break;
case BUSY: // others in middle of exchanging
break;
default: // impossible
break;
}
}
}
}
States WAITING and BUSY
If BUSY,
other threads exchanging,
so start again
![Page 197: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/197.jpg)
Art of Multiprocessor Programming 197197
The Exchanger Slot
• Exchanger is lock-free
• Because the only way an exchange can
fail is if others repeatedly succeeded or
no-one showed up
• The slot we need does not require
symmetric exchange
![Page 198: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/198.jpg)
Art of Multiprocessor Programming 198198
public class EliminationArray {
…
public T visit(T value, int range)
throws TimeoutException {
int slot = random.nextInt(range);
int nanodur = convertToNanos(duration, timeUnit));
return (exchanger[slot].exchange(value, nanodur)
}}
Back to the Stack: the
Elimination Array
![Page 199: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/199.jpg)
Art of Multiprocessor Programming 199199
public class EliminationArray {
…
public T visit(T value, int range)
throws TimeoutException {
int slot = random.nextInt(range);
int nanodur = convertToNanos(duration, timeUnit));
return (exchanger[slot].exchange(value, nanodur)
}}
Elimination Array
visit the elimination array
with fixed value and range
![Page 200: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/200.jpg)
Art of Multiprocessor Programming 200200
public class EliminationArray {
…
public T visit(T value, int range)
throws TimeoutException {
int slot = random.nextInt(range);
int nanodur = convertToNanos(duration, timeUnit));
return (exchanger[slot].exchange(value, nanodur)
}}
Elimination Array
Pick a random array entry
![Page 201: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/201.jpg)
Art of Multiprocessor Programming 201201
public class EliminationArray {
…
public T visit(T value, int range)
throws TimeoutException {
int slot = random.nextInt(range);
int nanodur = convertToNanos(duration, timeUnit));
return (exchanger[slot].exchange(value, nanodur)
}}
Elimination Array
Exchange value or time out
![Page 202: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/202.jpg)
Art of Multiprocessor Programming 202202
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
![Page 203: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/203.jpg)
Art of Multiprocessor Programming 203203
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
First, try to push
![Page 204: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/204.jpg)
Art of Multiprocessor Programming 204204
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
If I failed, backoff & try to eliminate
![Page 205: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/205.jpg)
Art of Multiprocessor Programming 205205
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
Value pushed and range to try
![Page 206: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/206.jpg)
Art of Multiprocessor Programming 206206
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
Only pop() leaves null,
so elimination was successful
![Page 207: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/207.jpg)
Art of Multiprocessor Programming 207207
public void push(T value) {
...
while (true) {
if (tryPush(node)) {
return;
} else try {
T otherValue =
eliminationArray.visit(value,policy.range);
if (otherValue == null) {
return;
}
}
Elimination Stack Push
Otherwise, retry push() on lock-free stack
![Page 208: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/208.jpg)
Art of Multiprocessor Programming 208208
public T pop() {
...
while (true) {
if (tryPop()) {
return returnNode.value;
} else
try {
T otherValue =
eliminationArray.visit(null,policy.range;
if (otherValue != null) {
return otherValue;
}
}
}}
Elimination Stack Pop
![Page 209: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/209.jpg)
Art of Multiprocessor Programming 209209
public T pop() {
...
while (true) {
if (tryPop()) {
return returnNode.value;
} else
try {
T otherValue =
eliminationArray.visit(null,policy.range;
if ( otherValue != null) {
return otherValue;
}
}
}}
Elimination Stack Pop
If value not null, other thread is a push(),
so elimination succeeded
![Page 210: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/210.jpg)
Art of Multiprocessor Programming 210210
Summary
• We saw both lock-based and lock-freeimplementations of
• queues and stacks
• Don’t be quick to declare a data structure inherently sequential
– Linearizable stack is not inherently sequential (though it is in the worst case)
• ABA is a real problem, pay attention
![Page 211: Concurrent Queues and Stacks - Brown Universitycs.brown.edu/courses/cs176/lectures/chapter_10_and_11.pdfConcurrent Queues and Stacks Companion slides for The Art of Multiprocessor](https://reader033.vdocuments.us/reader033/viewer/2022053001/5f0592717e708231d413a038/html5/thumbnails/211.jpg)
Art of Multiprocessor Programming 211211
This work is licensed under a 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
– http://creativecommons.org/licenses/by-sa/3.0/.
• 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.