The Push/Pull Model
- f Transactions
Eric Koskinen Yale University, New Haven United States Matthew Parkinson Microsoft Research, Cambridge United Kingdom
Appeared in PLDI 2015
CertiKOS Weekly Lunch 16 October 2015
The Push/Pull Model of Transactions Matthew Parkinson Eric - - PowerPoint PPT Presentation
The Push/Pull Model of Transactions Matthew Parkinson Eric Koskinen Yale University, New Haven Microsoft Research, Cambridge United States United Kingdom CertiKOS Weekly Lunch 16 October 2015 Appeared in PLDI 2015 Thread Thread Thread
Eric Koskinen Yale University, New Haven United States Matthew Parkinson Microsoft Research, Cambridge United Kingdom
Appeared in PLDI 2015
CertiKOS Weekly Lunch 16 October 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!