Software verification under weak memory consistency Viktor - PowerPoint PPT Presentation
Software verification under weak memory consistency Viktor Vafeiadis Max Planck Institute for Software Systems (MPI-SWS) January 2016 Joint work with Soham Chakraborty, Derek Dreyer, Marko Doko, Nick Giannarakis, Ori Lahav, Chinmay Narayan,
Software verification under weak memory consistency Viktor Vafeiadis Max Planck Institute for Software Systems (MPI-SWS) January 2016 Joint work with Soham Chakraborty, Derek Dreyer, Marko Doko, Nick Giannarakis, Ori Lahav, Chinmay Narayan, Joseph Tassarotti, Aaron Turon.
Sequential consistency Sequential consistency (SC): ◮ The standard model for concurrency. ◮ Interleave each thread’s atomic accesses. ◮ Almost all verification work assumes it. Initially, x = y = 0. x := 1; y := 1; a := y b := x In SC, this program cannot return a = b = 0. Viktor Vafeiadis Software verification under weak memory consistency 2
Store buffering in x86-TSO . . . cpu 1 cpu n write . . . read write-back Memory Initially, x = y = 0. x := 1; y := 1; a := y ; b := x ; This program can return a = b = 0. Viktor Vafeiadis Software verification under weak memory consistency 3
Owicki-Gries method (1976) OG = Hoare logic + rule for parallel composition { P 1 } c 1 { Q 1 } { P 2 } c 2 { Q 2 } the two proofs are non-interfering { P 1 ∧ P 2 } c 1 � c 2 { Q 1 ∧ Q 2 } Non-interference R ∧ P ⊢ R { u / x } for every: ◮ assertion R in the proof outline of one thread ◮ assignment x := u with precondition P in the proof outline of the other thread Viktor Vafeiadis Software verification under weak memory consistency 4
Standard OG is unsound for WM � � a � = 0 x := 1; y := 1; a := y b := x � � a � = 0 ∨ b � = 0 Viktor Vafeiadis Software verification under weak memory consistency 5
Standard OG is unsound for WM � � a � = 0 � � � � a � = 0 ⊤ x := 1; y := 1; � � � � x � = 0 y � = 0 a := y b := x � � � � x � = 0 y � = 0 ∧ ( a � = 0 ∨ b = x ) � � a � = 0 ∨ b � = 0 Viktor Vafeiadis Software verification under weak memory consistency 5
Standard OG is unsound for WM � � a � = 0 � � � � a � = 0 ⊤ x := 1; y := 1; � � � � x � = 0 y � = 0 a := y b := x � � � � x � = 0 y � = 0 ∧ ( a � = 0 ∨ b = x ) � � a � = 0 ∨ b � = 0 To regain soundness, strengthen the non-inference check. = ⇒ OGRA: Owicki-Gries for release-acquire (ICALP’15) Viktor Vafeiadis Software verification under weak memory consistency 5
Outline ◮ Introduction to the C11 weak memory model ◮ Release-acquire synchronization ◮ Per-location coherence ◮ Reasoning about WMM using program logics ◮ RSL (relaxed separation logic) ◮ FSL (fenced separation logic) ◮ GPS (ghosts, protocols and separation) ◮ Avoiding to reason about WMM ◮ Use reduction theorems Viktor Vafeiadis Software verification under weak memory consistency 6
The C11 memory model: Atomics Two types of locations Ordinary Atomic (Non-Atomic) Welcome to the Races are errors expert mode Viktor Vafeiadis Software verification under weak memory consistency 7
The C11 memory model: Hierarchy of atomics A spectrum of atomic accesses: Seq. consistent full memory fence Release write Acquire read no fence (x86); lwsync (PPC) no fence (x86); isync (PPC) Relaxed no fence Explicit primitives for fences Viktor Vafeiadis Software verification under weak memory consistency 8
Store buffering in C11 Initially x = y = 0. x . store(1 , rlx ); y . store(1 , rlx ); print ( y . load( rlx )); print ( x . load( rlx )); Can print 00 with the following execution: [ x = y = 0] po po rlx ( x , 1) rlx ( y , 1) W W rf rf po po R rlx ( y , 0) R rlx ( x , 0) Viktor Vafeiadis Software verification under weak memory consistency 9
Release-acquire synchronization Initially a = x = 0. a = 5; while ( x . load( acq ) == 0); x . store(1 , release ); print( a ); One possible execution: na ( a , 0) na ( x , 0) W W na ( a , 5) R acq ( x , 0) W sw W rel ( x , 1) R acq ( x , 1) R na ( a , 5) Happens before: hb = ( po ∪ sw ) + Viktor Vafeiadis Software verification under weak memory consistency 10
Coherence Programs with a single shared variable behave as under SC. x . store(1 , rlx ); x . store(2 , rlx ); a = x . load( rlx ); b = x . load( rlx ); The outcome a = 2 ∧ b = 1 is forbidden. mo rlx ( x , 1) rlx ( x , 2) W W reads-before R rlx ( x , 2) R rlx ( x , 1) ◮ Modification order, mo x , total order of writes to x . ◮ Reads-before : rb � ( rf − 1 ; mo ) ∩ ( � =) ◮ Coherence : hb ∪ rf x ∪ mo x ∪ rb x is acyclic for all x . Viktor Vafeiadis Software verification under weak memory consistency 11
Relaxed program logics ◮ RSL (relaxed separation logic, OOPSLA’13) ◮ FSL (fenced separation logic, VMCAI’16) ◮ GPS (ghosts & protocols, OOPSLA’14, PLDI’15)
Separation logic Key concept of ownership : ◮ Resourceful reading of Hoare triples. { P } C { Q } ◮ To access a non-atomic location, you must own it: { x �→ v } ∗ x { t . t = v ∧ x �→ v } { x �→ v } ∗ x = v ′ ; { x �→ v ′ } ◮ Disjoint parallelism: { P 1 } C 1 { Q 1 } { P 2 } C 2 { Q 2 } { P 1 ∗ P 2 } C 1 � C 2 { Q 1 ∗ Q 2 } Viktor Vafeiadis Software verification under weak memory consistency 13
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. {Q ( v ) ∗ W Q ( x ) } 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 Software verification under weak memory consistency 14
Release-acquire synchronization: message passing Initially a = x = 0. Let J ( v ) � v = 0 ∨ & a �→ 5. { & a �→ 0 ∗ W J ( x ) } { R J ( x ) } a = 5; while ( x . load( acq ) == 0); { & a �→ 5 ∗ W J ( x ) } { & a �→ 5 } x . store( release , 1); print( a ); { W J ( x ) } { & a �→ 5 } PL consequences: Ownership transfer works! Viktor Vafeiadis Software verification under weak memory consistency 15
Relaxed accesses Basically, disallow ownership transfer. ◮ Relaxed reads: { R Q ( x ) } t := x . load( rlx ) { R Q ( x ) ∧ ( Q ( t ) �≡ false ) } ◮ Relaxed writes: Q ( v ) = emp { W Q ( x ) } x . store( v , rlx ) { W Q ( x ) } Unsound because of dependency cycles! Viktor Vafeiadis Software verification under weak memory consistency 16
Dependency cycles Initially x = y = 0. if ( x . load ( rlx ) == 1) if ( y . load ( rlx ) == 1) y . store (1 , rlx ); x . store (1 , rlx ); C11 allows the outcome x = y = 1. Justification: R rlx ( x , 1) R rlx ( y , 1) Relaxed accesses don’t synchronize rlx ( y , 1) rlx ( x , 1) W W Viktor Vafeiadis Software verification under weak memory consistency 17
Dependency cycles Initially x = y = 0. if ( x . load ( rlx ) == 1) if ( y . load ( rlx ) == 1) y . store (1 , rlx ); x . store (1 , rlx ); C11 allows the outcome x = y = 1. What goes wrong: Non-relational invariants are unsound. x = 0 ∧ y = 0 The DRF-property does not hold. Viktor Vafeiadis Software verification under weak memory consistency 17
Dependency cycles Initially x = y = 0. if ( x . load ( rlx ) == 1) if ( y . load ( rlx ) == 1) y . store (1 , rlx ); x . store (1 , rlx ); C11 allows the outcome x = y = 1. How to fix this: Don’t use relaxed writes ∨ Strengthen the model Viktor Vafeiadis Software verification under weak memory consistency 17
Incorrect message passing int a ; atomic_int x = 0; a = 5; if ( x . load( rlx ) � = 0) { x . store(1 , rlx ); print ( a ); } na ( a , 5) R rlx ( x , 1) W race W rlx ( x , 1) R na ( a , ? ) Viktor Vafeiadis Software verification under weak memory consistency 18
Message passing with C11 memory fences int a ; atomic_int x = 0; a = 5; if ( x . load( rlx ) � = 0) { fence( release ); fence( acq ); x . store(1 , rlx ); print ( a ); } na ( a , 5) R rlx ( x , 1) W sw F rel F acq W rlx ( x , 1) R na ( a , 5) Viktor Vafeiadis Software verification under weak memory consistency 18
Reasoning about fences ◮ Introduce two ‘modalities’ in the logic { P } fence( release ) {△ P } { W Q ( x ) ∗ △Q ( v ) } x . store( v , rlx ) { W Q ( x ) } { R Q ( x ) } t := x . load( rlx ) { R Q [ t :=emp] ( x ) ∗ ▽Q ( t ) } {▽ P } fence( acq ) { P } Viktor Vafeiadis Software verification under weak memory consistency 19
Reasoning about fences Let Q ( v ) � v = 0 ∨ & a �→ 5. { & a �→ 0 ∗ W Q ( x ) ∗ R Q ( x ) } t = x . load( rlx ); { & a �→ 0 ∗ W Q ( x ) } {▽ ( t = 0 ∨ & a �→ 5) } 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 ); } {⊤} {⊤} Viktor Vafeiadis Software verification under weak memory consistency 20
GPS: A better logic for release-acquire Three key features: ◮ Location protocols ◮ Ghost state/tokens ◮ Escrows for ownership transfer Example (Racy message passing) Initially, x = y = 0. x . store(1 , rlx ); x . store(1 , rlx ); t = y . load( acq ); t ′ = x . load( rlx ); y . store(1 , rel ); y . store(1 , rel ); Cannot get t = 1 ∧ t ′ = 0. Viktor Vafeiadis Software verification under weak memory consistency 21
Recommend
More recommend
Explore More Topics
Stay informed with curated content and fresh updates.