Program logics for relaxed consistency UPMARC Summer School 2014 Viktor Vafeiadis Max Planck Institute for Software Systems (MPI-SWS) 2nd Lecture, 29 July 2014
Recap Topics covered yesterday: ◮ The C11 memory model ◮ Separation logic ◮ Relaxed separation logic Today: ◮ Compare and swap ◮ GPS ◮ Advanced features Viktor Vafeiadis Program logics for relaxed consistency 2/30
Recap: Rules for release/acquire accesses Ownership transfer by rel-acq synchronizations. ◮ Atomic allocation ❀ pick loc. invariant Q . � � � � Q ( v ) x = alloc( v ); W Q ( x ) ∗ R Q ( x ) ◮ Release write ❀ give away permissions. � � � � W Q ( x ) ∗ Q ( v ) x . store( v , rel ); W Q ( x ) ◮ Acquire read ❀ gain permissions. � � � � R Q ( x ) t = x . load( acq ); Q ( t ) ∗ R Q [ t :=emp] ( x ) Viktor Vafeiadis Program logics for relaxed consistency 3/30
Recap: relaxed accesses Basically, disallow ownership transfer. ◮ Relaxed reads: R Q ( x ) ∧ � � R Q ( x ) t = x . load ( rlx ) ( Q ( t ) �≡ false) ◮ Relaxed writes: Q ( v ) = emp � � � � W Q ( x ) x . store ( v , rlx ) W Q ( x ) Viktor Vafeiadis Program logics for relaxed consistency 4/30
Compare and swap (CAS) A standard primitive for implementing concurrent algorithms x . CAS( v , v ′ , M ) def = atomic { if ( x . load( M ) == v ) { x . store( v ′ , M ); return true; } return false; } Viktor Vafeiadis Program logics for relaxed consistency 5/30
Reasoning about CAS in RSL ◮ New assertion form, P := . . . | C Q ( x ). ◮ “Permission to do a CAS” ◮ Duplicable: C Q ( x ) ⇐ ⇒ C Q ( x ) ∗ C Q ( x ) ◮ Also allows writing: C Q ( x ) ⇐ ⇒ C Q ( x ) ∗ W Q ( x ) ◮ And reading without ownership transfer: C Q ( x ) ⇐ ⇒ C Q ( x ) ∗ R emp ( x ) Viktor Vafeiadis Program logics for relaxed consistency 6/30
Reasoning about CAS in RSL Allocation rule: � � � � Q ( v ) x = alloc( v ); C Q ( x ) CAS rule: t ∧ P ∗ Q ( v ) ⇒ Q ( v ′ ) ∗ R ¬ t ∧ P ⇒ R X ∈ { rel , rlx } ⇒ Q ( v ) ≡ emp X ∈ { acq , rlx } ⇒ Q ( v ′ ) ≡ emp � � � � t = x . CAS( v , v ′ , X ) C Q ( x ) ∗ P R Viktor Vafeiadis Program logics for relaxed consistency 7/30
Mutual exclusion locks Attach a ‘resource invariant’ at each lock: Lock ( x , J ) ⇐ ⇒ Lock ( x , J ) ∗ Lock ( x , J ) Specifications for mutex operations: � � � � x = new-lock () Lock ( x , J ) J � � � � Lock ( x , J ) lock ( x ) Lock ( x , J ) ∗ J � � � � J ∗ Lock ( x , J ) unlock ( x ) Lock ( x , J ) Viktor Vafeiadis Program logics for relaxed consistency 8/30
Mutual exclusion locks Q J ( v ) def Let = ( v = 0 ∧ emp) ∨ ( v = 1 ∧ J ) Lock ( x , J ) def = C Q J ( x ) new-lock () def = lock ( x ) def = � � J � � Lock ( x , J ) res = alloc (1) repeat � � Lock ( res , J ) � � Lock ( x , J ) unlock ( x ) def t = x . CAS(1 , 0 , acq ) = � � �� Lock ( x , J ) ∗ t ⇒ J � � J ∗ Lock ( x , J ) until t x . store(1 , rel ) � � J ∗ Lock ( x , J ) � � Lock ( x , J ) Viktor Vafeiadis Program logics for relaxed consistency 9/30
GPS: Towards a better logic for C11 ◮ Protocols ◮ Ghosts & escrows
GPS: A better logic for release-acquire Three key features: ◮ Location ✭✭✭✭✭ invariants protocols ❤❤❤❤❤ ✭ ❤ ◮ Ghost state/tokens ◮ Escrows for ownership transfer Example (Racy message passing) Initially, x = y = 0. x . store(1 , rel ); x . store(1 , rel ); t = y . load( acq ); t ′ = x . load( acq ); y . store(1 , rel ); y . store(1 , rel ); Cannot get t = 1 ∧ t ′ = 0. Viktor Vafeiadis Program logics for relaxed consistency 11/30
Racy message passing in GPS Protocol for x : A: x = 0 B: x = 1 Protocol for y : C: y = 0 D: y = 1 ∧ x . st ≥ B Acquire reads gain knowledge, not ownership. � � x . st ≥ A ∧ y . st ≥ C � � x . st ≥ A ∧ y . st ≥ C t = y . load( acq ); x . store(1 , rel ); t = 0 ∧ x . st ≥ A � � x . st ≥ B ∧ y . st ≥ C ∨ t = 1 ∧ x . st ≥ B y . store(1 , rel ); t ′ = x . load( acq ); � � x . st ≥ B ∧ y . st ≥ D t = 0 ∨ ( t = 1 ∧ t ′ = 1) � � Viktor Vafeiadis Program logics for relaxed consistency 12/30
Rules for reads and writes Read rule: ∀ s ′ ≥ τ s . inv τ ( s ′ , t ) ∗ P ⇒ Q Q ⇔ Q ∗ Q ∃ s ′ . x . st ≥ τ s ′ x . st ≥ τ s t = x . load( acq ); ∗ P ∗ P ∗ Q Write rule: P ⇛ inv τ ( s ′′ , v ) ∗ Q ∀ s ′ ≥ τ s . inv τ ( s ′ , _) ∗ P ⇒ s ′′ ≥ τ s ′ x . st ≥ τ s ′′ ∗ Q � � � � x . st ≥ τ s ∗ P x . store( v , rel ); Viktor Vafeiadis Program logics for relaxed consistency 13/30
GPS ghosts and escrows We can create ghost unduplicable tokens: K is fresh P ⇛ P ∗ K K ∗ K ⇒ false We can also create escrows: P ∗ P ⇒ false Q ⇛ Esc ( P , Q ) Esc ( P , Q ) ∗ P ⇛ Q Escrows are duplicable: Esc ( P , Q ) ⇐ ⇒ Esc ( P , Q ) ∗ Esc ( P , Q ) but only one component can ‘unlock’ them. Viktor Vafeiadis Program logics for relaxed consistency 14/30
GPS ghosts and escrows To gain ownership, we use ghost state & escrows. P ∗ P ⇒ false Q ⇛ Esc ( P , Q ) Esc ( P , Q ) ∗ P ⇛ Q Example (Message passing using escrows) Invariant for x : x = 0 ∨ Esc ( K , & a �→ 7). � � � � & a �→ 0 K a = 7; if ( x . load( acq ) � = 0) � � � � & a �→ 7 K ∗ Esc ( K , & a �→ 7) � � � � Esc ( K , & a �→ 7) & a �→ 7 x . store(1 , rel ); print ( a ); Viktor Vafeiadis Program logics for relaxed consistency 15/30
Rule for CAS With a successful CAS we can gain not only knowledge, but also ownership: ∀ s ′′ ≥ τ s . inv τ ( s ′′ , v ) ∗ P ⇛ inv τ ( s ′ , v ′ ) ∗ Q ∧ s ′ ≥ τ s ′′ ∀ s ′′ ≥ τ s . ∀ v ′′ � = v . inv τ ( s ′′ , v ′′ ) ∗ P ⇒ R R ⇔ R ∗ R ( t ∧ x . st ≥ τ s ′ ∗ Q ) x . st ≥ τ s t = x . CAS ( v , v ′ , rel-acq ); ∗ P ∨ ¬ t ∧ P ∗ R Viktor Vafeiadis Program logics for relaxed consistency 16/30
Reasoning about advanced C11 features (Work in progress) ◮ Fences ◮ Consume reads
� � � � � � � � Message passing int a ; atomic_int x = 0; a = 7; if ( x . load( acq ) � = 0) { x . store(1 , rel ); print ( a ); } W na ( x , 0) W na ( a , 7) R acq ( x , 1) sw W rel ( x , 1) R na ( a , 7) Viktor Vafeiadis Program logics for relaxed consistency 18/30
� � � � � � � � Incorrect message passing int a ; atomic_int x = 0; a = 7; if ( x . load( rlx ) � = 0) { x . store(1 , rlx ); print ( a ); } W na ( x , 0) W na ( a , 7) R rlx ( x , 1) race W rlx ( x , 1) R na ( a , 7) Viktor Vafeiadis Program logics for relaxed consistency 18/30
� � � � � � � � � � Message passing with C11 memory fences int a ; atomic_int x = 0; a = 7; if ( x . load( rlx ) � = 0) { fence( release ); fence( acq ); x . store(1 , rlx ); print ( a ); } W na ( x , 0) W na ( a , 7) R rlx ( x , 1) sw � Fence acq Fence rel W rlx ( x , 1) R na ( a , 7) Viktor Vafeiadis Program logics for relaxed consistency 18/30
Reasoning about fences Introduce two ‘modalities’ in the logic. � � � � P fence( release ) △ P � � � � ∇ P fence( acq ) P � � � � R Q ( x ) t := x . load( rlx ) R Q [ t :=emp] ( x ) ∗ ∇Q ( t ) � � � � W Q ( x ) ∗ △Q ( v ) x . store( v , rlx ) W Q ( x ) Viktor Vafeiadis Program logics for relaxed consistency 19/30
Reasoning about fences Let Q ( v ) def = v = 0 ∨ & a �→ 5. � � & a �→ 0 ∗ W Q ( x ) ∗ R Q ( x ) � � & a �→ 0 ∗ W Q ( x ) t = x . load( rlx ); � � a = 5; ∇ ( t = 0 ∨ & a �→ 5) � � & a �→ 5 ∗ W Q ( x ) if ( t � = 0) fence( release ); fence( acq ); � � � � △ (& a �→ 5) ∗ W Q ( x ) & a �→ 5 x . store(1 , rlx ); print ( a ); } � � � � true true Viktor Vafeiadis Program logics for relaxed consistency 20/30
Why two modalities? Consider the program, where initially x = y = 0: t ′ = y . load( rlx ); if ( t ′ � = 0) { a = 5; t = x . load( rlx ); fence( release ); if ( t � = 0) fence( acq ); x . store(1 , rlx ); y . store(1 , rlx ); print ( a ); } If ∇ P ⇒ △ P , we can ‘verify’ this program. But the program is racy. Viktor Vafeiadis Program logics for relaxed consistency 21/30
� � � � Release-consume synchronization Initially a = x = 0. a = 5; t = x . load ( consume ); x . store ( release , & a ); if ( t � = 0) print ( ∗ t ); This program cannot crash nor print 0. Justification: W na ( a , 5) R con ( x , & a ) Release-consume synchronization W rel ( x , & a ) R na ( a , 5) Viktor Vafeiadis Program logics for relaxed consistency 22/30
Recommend
More recommend