Professional Documents
Culture Documents
CSE613 Lecture 17 PDF
CSE613 Lecture 17 PDF
CSE613 Lecture 17 PDF
Lecture 17
( Concurrent Data Structures:
Queues and Stacks )
Rezaul A. Chowdhury
Department of Computer Science
SUNY Stony Brook
Spring 2012
Liveness Property
Something good eventually happens
Needed for progress ( e.g., no deadlock )
Correctness Properties
Sequential Consistency
Method calls should appear to happen in a one-at-a-time
sequential order
For each thread method calls should appear to take effect
in program order
Thread 1
Thread 2
q.deq( y )
q.enq( x )
q.enq( y )
q.deq( x )
Correctness Properties
Sequential Consistency
Method calls should appear to happen in a one-at-a-time
sequential order
For each thread method calls should appear to take effect
in program order
Thread 1
q.enq( x )
q.enq( y )
q.deq( x )
Thread 2
Sequentially Consistent
( one way )
q.deq( y )
Correctness Properties
Sequential Consistency
Method calls should appear to happen in a one-at-a-time
sequential order
For each thread method calls should appear to take effect
in program order
Thread 1
q.enq( y )
q.enq( x )
q.deq( y )
Thread 2
Sequentially Consistent
( another way )
q.deq( x )
Correctness Properties
Sequential Consistency
Method calls should appear to happen in a one-at-a-time
sequential order
For each thread method calls should appear to take effect
in program order
Sequential Consistency is not compositional
Thread 1
Thread 2
p.enq( x )
q.enq( y )
q.enq( x )
p.enq( y )
p.deq( y )
q.deq( x )
Correctness Properties
Sequential Consistency
Method calls should appear to happen in a one-at-a-time
sequential order
For each thread method calls should appear to take effect
in program order
Sequential Consistency is not compositional
Thread 1
Thread 2
p.enq( x )
q.enq( y )
q.enq( x )
p.enq( y )
p.deq( y )
q.deq( x )
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.deq( y )
q.enq( x )
q.enq( y )
q.deq( x )
Time
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.deq( y )
q.enq( x )
q.enq( y )
q.deq( x )
Time
Linearizable
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.enq( x )
q.deq( y )
q.enq( y )
Time
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.enq( x )
q.deq( y )
q.enq( y )
Time
Not Linearizable
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.enq( x )
q.enq( y )
q.deq( y )
q.deq( x )
Time
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.enq( x )
q.deq( y )
q.enq( y )
q.deq( x )
Time
Linearizable
( one way )
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
q.enq( x )
q.enq( y )
q.deq( y )
q.deq( x )
Time
Linearizable
( another way )
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
push( x )
pop( y )
push( y )
push( z )
pop( x )
Time
Correctness Properties
Linearizability
Each method call should appear to take effect
instantaneously at some moment between its invocation
and response
Compositional
Thread 1
Thread 2
push( x )
pop( y )
push( z )
push( y )
pop( x )
Time
Not Linearizable
1.
2.
3.
4.
AtomicInteger size;
5.
6.
int capacity;
7.
head
tail
null
8.
capacity = _capacity;
9.
1.
10.
tail = head;
2.
public T value;
11.
3.
12.
4.
public Node( T x ) {
13.
notFullCondition = enqLock.newCondition( );
5.
value = x;
14.
6.
next = null;
15.
notEmptyCondition = deqLock.newCondition( );
7.
16.
8.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
2.
3.
enqLock.lock( );
4.
try {
tail
5.
6.
notFullCondition.await( );
7.
8.
tail.next = tail = e;
9.
if ( size.getAndIncrement( ) == 0 )
10.
mustWakeDequeuers = true;
} finally {
11.
12.
enqLock.unlock( );
13.
14.
if ( mustWakeDequeuers ) {
15.
deqLock.lock( );
16.
try {
17.
notEmptyCondition.signalAll( );
} finally {
18.
19.
deqLock.unlock( );
20.
21.
22.
head
}
}
null
1.
f
g
2.
3.
enqLock.lock( );
4.
try {
tail
5.
6.
notFullCondition.await( );
7.
8.
tail.next = tail = e;
9.
if ( size.getAndIncrement( ) == 0 )
10.
mustWakeDequeuers = true;
} finally {
11.
12.
enqLock.unlock( );
13.
14.
if ( mustWakeDequeuers ) {
15.
deqLock.lock( );
16.
try {
17.
notEmptyCondition.signalAll( );
} finally {
18.
19.
deqLock.unlock( );
20.
21.
22.
head
}
}
null
1.
f
g
2.
T result;
3.
4.
deqLock.lock( );
5.
try {
tail
while ( size.get( ) == 0 )
6.
7.
notEmptyCondition.await( );
8.
result = head.next.value;
9.
head = head.next;
10.
if ( size.getAndDecrement( ) == capacity ) {
mustWakeEnqueuers = true;
11.
12.
13.
} finally { deqLock.unlock( ); }
14.
if ( mustWakeEnqueuers ) {
15.
enqLock.lock( );
16.
try {
17.
notFullCondition.signalAll( );
18.
} finally { enqLock.unlock( ); }
19.
20.
return result;
21.
head
null
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
1.
2.
T result;
3.
4.
deqLock.lock( );
5.
try {
tail
while ( size.get( ) == 0 )
6.
7.
notEmptyCondition.await( );
8.
result = head.next.value;
9.
head = head.next;
10.
if ( size.getAndIncrement( ) == capacity ) {
mustWakeEnqueuers = true;
11.
12.
13.
} finally { deqLock.unlock( ); }
14.
if ( mustWakeEnqueuers ) {
15.
enqLock.lock( );
16.
try {
17.
notFullCondition.signalAll( );
18.
} finally { enqLock.unlock( ); }
19.
20.
return result;
21.
head
null
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
1.
2.
T result;
3.
4.
deqLock.lock( );
5.
try {
tail
while ( size.get( ) == 0 )
6.
7.
notEmptyCondition.await( );
8.
result = head.next.value;
9.
head = head.next;
10.
if ( size.getAndIncrement( ) == capacity ) {
mustWakeEnqueuers = true;
11.
12.
13.
} finally { deqLock.unlock( ); }
14.
if ( mustWakeEnqueuers ) {
15.
enqLock.lock( );
16.
try {
17.
notFullCondition.signalAll( );
18.
} finally { enqLock.unlock( ); }
19.
20.
return result;
21.
head
null
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
1.
null
2.
T result;
3.
4.
deqLock.lock( );
5.
try {
tail
while ( size.get( ) == 0 )
6.
7.
notEmptyCondition.await( );
8.
result = head.next.value;
9.
head = head.next;
10.
if ( size.getAndIncrement( ) == capacity ) {
mustWakeEnqueuers = true;
11.
12.
13.
} finally { deqLock.unlock( ); }
14.
if ( mustWakeEnqueuers ) {
15.
enqLock.lock( );
16.
try {
17.
notFullCondition.signalAll( );
18.
} finally { enqLock.unlock( ); }
19.
20.
return result;
21.
head
null
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
1.
tail
null
1.
2.
public T value;
3.
4.
5.
value = _value;
6.
7.
8.
}
}
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
tail
2. CAS tail
null
public void enq( T value ) {
2.
3.
while ( true ) {
4.
5.
6.
if ( last == tail.get( ) ) {
7.
if ( next == null ) {
if ( last.next.compareAndSet( next, node ) ) {
8.
9.
10.
return;
11.
}
} else { tail.compareAndSet( last, next ); }
12.
13.
14.
15.
}
}
g
1. CAS next
Source: Herlihy & Shavit.,
The Art of Multiprocessor Programming, 1st Edition
1.
2.
3.
4.
5.
6.
if ( first == head.get( ) ) {
if ( first == last ) {
7.
if ( next == null ) {
8.
9.
10.
11.
12.
13.
T value = next.value;
14.
15.
16.
17.
18.
19.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
Exponential Backoff
1.
2.
3.
int limit;
4.
5.
6.
minDelay = min;
7.
maxDelay = min;
8.
limit = minDelay;
9.
10.
11.
12.
13.
14.
Thread.sleep( delay );
15.
16.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
1.
2.
3.
4.
5.
6.
7.
public T value;
8.
9.
10.
value = _value;
11.
next = null;
12.
13.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
1.
2.
3.
node.next = oldTop;
4.
5.
6.
7.
8.
while ( true ) {
9.
10.
else { backoff.backoff( ); }
11.
12.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
1.
2.
3.
node.next = oldTop;
4.
5.
6.
7.
8.
while ( true ) {
9.
10.
else { backoff.backoff( ); }
11.
12.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
1.
2.
3.
node.next = oldTop;
4.
5.
6.
7.
8.
while ( true ) {
9.
10.
else { backoff.backoff( ); }
11.
12.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
2.
3.
if ( oldTop == null ) {
throw new EmptyException( );
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
else { backoff.backoff( ); }
15.
16.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
CAS
d
1.
2.
3.
if ( oldTop == null ) {
throw new EmptyException( );
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
else { backoff.backoff( ); }
15.
16.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
Elimination-Backoff Stack
C: pop ( )
A: return ( b )
C: return ( d )
A: pop ( )
top
d
B: push ( b )
Shared Lock-Free Stack
Lock-Free
Elimination
Array
B: return ( )
Elimination Array
1.
2.
3.
4.
Random rand;
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
2.
3.
4.
5.
6.
7.
while ( true ) {
8.
9.
else try {
10.
11.
12.
13.
14.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
( modified )
2.
3.
4.
5.
else try {
6.
7.
8.
9.
10.
}
}
Source: Herlihy & Shavit., The Art of Multiprocessor Programming, 1st Edition
( modified )