The Push/Pull Model
- f Transactions
Eric Koskinen IBM Research, New York United States Matthew Parkinson Microsoft Research, Cambridge United Kingdom
PLDI 2015
The Push/Pull Model of Transactions Matthew Parkinson Eric - - PowerPoint PPT Presentation
The Push/Pull Model of Transactions Matthew Parkinson Eric Koskinen IBM Research, New York Microsoft Research, Cambridge United States United Kingdom PLDI 2015 Thread Thread Thread Thread 1 2 3 4 rd wr put get enq deq add rm
Eric Koskinen IBM Research, New York United States Matthew Parkinson Microsoft Research, Cambridge United Kingdom
PLDI 2015
Concurrent HashMap Concurrent Queue Concurrent List
Thread 1 Thread 3 Thread 2 Thread 4
put get enq deq add rm
Shared Memory
rd wr
Concurrent HashMap Concurrent Queue Concurrent List
Thread 1 Thread 3 Thread 2 Thread 4
put get enq deq add rm
Shared Memory
rd wr
Adding atomic to a language . . . Version 4.7
Concurrent HashMap Concurrent Queue Concurrent List
Thread 1 Thread 3 Thread 2 Thread 4
put get enq deq add rm
Shared Memory
rd wr
Adding atomic to a language . . .
Concurrent HashMap Concurrent Queue Concurrent List
Thread 1 Thread 3 Thread 2 Thread 4
put get enq deq add rm
Shared Memory
rd wr
many issues arise in the implementation.
Adding atomic to a language . . .
Thread
atomic { x := 3; y := 9; }
x changed? y changed?
Thread
atomic { x := 3; y := 9; }
all ok?
Interleaved execution equivalent to some serial execution.
Interleaved execution equivalent to some serial execution and cannot observe intermediate state.
Thread
atomic { x := 3; y := 9; }
Thread
atomic { stk.push(4); ht.get('a'); }
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
Thread
atomic { if(b) {
} else … }
Thread
atomic { while(…){ if(x>MAX)
… }
Thread
atomic { if(b) {
} else … }
Thread
atomic { while(…){ if(x>MAX)
… }
Linearizable Operation Linearizable Operation
Thread Thread
{tx c1, σ1} {tx c2, σ2}
Thread Thread
{tx c1, σ1} {tx c2, σ2}
example language:
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} G ⟨op1,_⟩ ⟨op2,_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} G
Closed under log prefix
⟨op1,_⟩ ⟨op2,_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} G
Closed under log prefix
⟨op1,_⟩ ⟨op2,_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} G
⟨op1,_⟩ ⟨op2,_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2}
atomic {
… } atomic {
… } G ⟨ht.map(3,x),σ,σ1,c⟩ ⟨ht.map(7,2),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… }
G
1
⟨ht.map(3,x),σ,σ1,c⟩ ⟨q.enq(‘a’),σ1,σ'1,c1⟩ ⟨ht.map(7,2),_,gUC⟩
1
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… }
G Criterion (i): Criterion (ii): Criterion (iii): L1 allows ⟨m,σ1,σ'1,id⟩
fresh(id)
1
⟨ht.map(3,x),σ,σ1,c⟩ ⟨q.enq(‘a’),σ1,σ'1,c1⟩ ⟨ht.map(7,2),_,gUC⟩
1
{tx c1, σ1, L1}, G ➝ {tx c'1, σ'1, L1·[op,σ1,σ'1,c1]}, G
append Possible next op Valid semantics of log
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… }
G
⟨ht.map(7,2),_,gUC⟩ ⟨ht.map(3,x),σ,σ1,c⟩ ⟨q.enq(‘a’),σ1,σ'1,c1⟩ {tx c'1, σ'1, L1·[op,σ1,σ'1,c1]}, G ➝ {tx c1, σ1, L1}, G
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2}
atomic {
… } atomic {
… } ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ G ⟨ht.map(7,2),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2}
atomic {
… } atomic {
… } ⟨ht.map(3,x),_⟩ Push ⟨q.enq(‘a’),_⟩ ⟨ht.map(3,x),_,gUC⟩ G ⟨ht.map(7,2),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2}
atomic {
… } atomic {
… }
G
Criterion (i): Criterion (ii): Criterion (iii):
G allows op
Act as if op happens next No conflict w/ other uncmted
Left-mover over logs ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ {tx c, σ, `L·[op]·L'}, G ➝ {tx c, σ, `L·[op]·L'}, G·[op,gUC] ⎣G⎦gUC ∖ ⎣L1⎦pushed ◀ op
Uncommitted
Application: Out-of-order PUSHing with redo-logs Application: Optimism vs. Pessimism
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.map(3,x),_⟩
G
L2 allows op Criterion (i): Criterion (ii):
Criterion (iii):
Didn’t pull already Local log allows op Can act as if op happened earlier
⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ {tx c2, σ2, L2}, G1·[op,g]·G2 ➝ {tx c2, σ2, L2·[op]}, G1·[op,g]·G2
Application: Opacity [GK’08] and dependent transactions [RRHW’09]
⟨q.enq(‘a’),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… }
⟨ht.get(5),_⟩ G ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… }
⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩
G ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ G ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
⟨q.enq(‘a’),_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ G ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.get(9),_⟩
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ G ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.get(9),_⟩
cmt(G, L1, G')
⎣L1⎦pulled ⊆ ⎣G⎦gC Criterion (ii): Criterion (iii): Criterion (iv): L1 ⊆ G Criterion (i):
fin(c1)
Pushed all my stuff Pulled ops are committed Swap my flags from gUC to gC
{tx c1, σ1, L1}, G ➝ {tx c1, σ1, L1}, G’
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ ⟨
G
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩
G
(Local log is still allowed, even with element removed.)
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ G
(Everything I subsequently pushed could have been pushed earlier.)
Application: Inverses or “compensating actions”
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ G
q . d e q ( )
Thread Thread
{tx c1, σ1, L1} {tx c2, σ2, L2} atomic {
… } atomic {
… } ⟨ht.get(5),_,gUC⟩ ⟨ht.get(5),_⟩ ⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩ ⟨q.enq(‘a’),_⟩ G
q . d e q ( )
Simulation with uninterleaved machine Closure under log rewind Preservation invariant, universal quantification
universal quantifying over local log rewind.
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
example: Don’t PULL uncommitted effects.
Other Applications.
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
delay commit (or cascading aborts)
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
Mixing hardware TM with transactional boosting Models that are yet-to-come.
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
The PUSH/PULL Model
Push
⟨ht.get(5),_⟩
Pull
⟨ht.map(3,x),_⟩ ⟨ht.map(3,x),_⟩ ⟨q.enq(‘a’),_⟩ ⟨q.enq(‘a’),_,gUC⟩ ⟨ht.map(3,x),_,gUC⟩ ⟨ht.map(7,2),_,gUC⟩
Eric Koskinen IBM Research, New York United States Matthew Parkinson Microsoft Research, Cambridge United Kingdom
Thank you!