Introduction On Validity of Program Transformations in the Java Memory Model 47 J. ˇ 46 Sevˇ c´ ık and D. Aspinall 5. For all reads r ∈ A i − C i − 1 we have W i ( r ) ≤ hb i r . 6. For all reads r ∈ C i − C i − 1 we have W ( r ) ∈ C i − 1 . 3. | t | > 0 implies π K (() t 0 ) = St (start action first), 7. If y ∈ C i is an external action and x ≤ hb y then x ∈ C i . 4. π K (() t i ) = Fin implies i = | t | − 1 (finish action last). On Validity of Program Transformations in the Java Memory Model 45 5. θ = θ init implies ∀ i. 1 ≤ i < | t | − 1 → ∃ v. π K (() t i ) = Wr( v ) ∨ π K (() t i ) = The original definition of legality from [11,18] di ff ers in rules 2 and 6, and adds Wr v ( v ) and π K (() t | t | − 1 ) = Fin (initialisation thread only contains writes). Definition 2. An execution E is a tuple E = � A, P, ≤ po , ≤ so , W, V � , where rule 8: A ⊆ A is a set of actions; P is a program, represented as a thread-indexed set of The well-formedness of programs should not be hard to establish for any rea- 2. ≤ hb i | C i = ≤ hb | C i . memory traces; the partial order ≤ po ⊆ A × A is the program order, which is a sonable sequential language. 6. For all reads r ∈ C i − C i − 1 we have W ( r ) ∈ C i − 1 and W i ( r ) ∈ C i − 1 . union of total orders on actions of each thread; ≤ so ⊆ A × A is the synchronisation The next definition places some sensible restriction on executions. 8. If x < ssw i y ≤ hb i z and z ∈ C i − C i − 1 , then x < sw j y for all j ≥ i , where order, which is a total order on all synchronisation actions in A ; V :: A ⇒ V is < ssw i is the transitive reduction of ≤ hb i without any ≤ po i edges, and the a value-written function that assigns a value to each write from A ; W :: A ⇒ A Definition 7. We say that an execution � A, P, ≤ po , ≤ so , W, V � is well-formed transitive reduction of ≤ hb i is a minimum relation such that its transitive is a write-seen function that assigns a write to each read action from A , the if closure is ≤ hb i . W ( r ) denotes the write seen by r , i.e. the value read by r is V ( W ( r )) . x = 0, y = 0, y = 0 memory model 1. A is finite. The reasons for weakening the rules are invalidity of reordering of independent Definition 3. In an execution with synchronisation order ≤ so , an action a 2. ≤ po restricted on actions of one thread is a total order, ≤ po does not relate statements, broken JMM causality tests 17–20 [21], and redundancy. For details, A JMM Definitions synchronises-with an action b (written a < sw b ) if a ≤ so b and a and b sat- actions of di ff erent threads. see [5,6]. isfy one of the following conditions: 3. ≤ so is total on synchronisation actions of A . For reasoning about validity of reordering, we define observable behaviours of The following definitions are mostly from [11,18]; however, we have weakened 4. ≤ so is consistent with ≤ po . – a is an unlock on monitor m and b is a lock on monitor m , executions and programs. Intuitively, a program P has an observable behaviour the definition of execution legality as suggested in [5]. We use letters θ for thread 5. W is properly typed: for every non-volatile read r ∈ A , W ( r ) is a non-volatile – a is a volatile write to v and b is a volatile read from v . B if B is a subset of external actions of some execution of P , and B is downward names, m for synchronisation monitor names, and v for variables (i.e., memory ‣ contract between programmer write; for every volatile read r ∈ A , W ( r ) is a volatile write. closed on happens-before order (restricted to external actions). The JMM cap- locations, in examples, x , y , v etc.). The abstract type V will denote values. r1 = x r2 = y 6. Locking is proper: for all lock actions l ∈ A on monitors m and all threads θ Definition 4. The happens-before order of an execution is the transitive closure tures non-termination as a behaviour in the definition of allowable behaviours. The starting point is the notion of action . di ff erent from the thread of l , the number of locks in θ before l in ≤ so is the of the composition of its synchronises-with order and its program order, i.e. ≤ hb = ( < sw ∪ ≤ po ) + . same as the number of unlocks in θ before l in ≤ so . Definition 1. An action is a memory-related operation; it is modelled by an Definition 9. An execution � A, P, ≤ po , ≤ so , W, V � with happens-before order 7. Program order is intra-thread consistent: for each thread θ , the trace of θ in abstract type A with the following properties: (1) Each action belongs to one ≤ hb has a set of observable behaviours O if for all x ∈ O we have y ≤ hb x To relate a (sequential) program to a sequence of actions performed by one thread, we will denote it by T ( a ) . (2) An action is one of the following action E is sequentially valid for P θ . and programming environment or y ≤ so x implies y ∈ O or T ( y ) = θ init . Moreover, there is no x ∈ O such that thread we must define a notion of sequential validity . We consider single-thread kinds : 8. ≤ so is consistent with W : for every volatile read r of a variable v we have T ( x ) = θ init . programs as sets of sequences of pairs of an action kind and a value, which we W ( r ) ≤ so r and for any volatile write w to v , either w ≤ so W ( r ) or r ≤ so w . y = 1 x = 1 – volatile read of v , – normal write to v , call traces . A multi-thread program is a set of single-thread programs indexed – thread start , 9. ≤ hb is consistent with W : for all reads r of v it holds that r �≤ hb W ( r ) and The allowable behaviours may contain a special external hang action if the ex- – volatile write to v , – lock on m , by thread identifiers. – thread finish , there is no intervening write w to v , i.e. if W ( r ) ≤ hb w ≤ hb r and w writes ecution does not terminate. We will use the notation Ext( A )) for all external – normal read from v , – unlock on m , – external action . to v then W ( r ) = w . actions of set A , i.e., Ext( A ) = { a | K ( a ) = Ex } . Definition 5. Given an execution E = � A, P, ≤ po , ≤ so , W, V � , the action trace ‣ specifies which writes can be We denote the action kind of a by K ( a ) , the action kinds will be abbreviated to 10. The initialisation thread θ init finishes before any other thread starts, i.e., of thread θ in E , denoted Tr E ( θ ) , is the list of actions of thread θ in the order Definition 10. A finite set of actions B is an allowable behaviour of a program Rd v ( v ) , Wr v ( v ) , Rd( v ) , Wr( v ) , L( m ) , U( m ) , St , Fin , Ex . An action kind also ∀ a, b ∈ A. K ( a ) = Fin ∧ T ( a ) = θ init ∧ K ( b ) = St ∧ T ( b ) � = θ init → a ≤ so b . ≤ po . The trace of thread θ in E , written Tr E ( θ ) is the list of action kinds and includes the associated variable or monitor. The volatile read, volatile write, lock, P if either corresponding values obtained from the action trace (i.e., V ( W ( a )) if a is a read, The following definition of legal execution constitutes the core of the Java Mem- unlock, start, finish actions are called synchronisation actions . V ( a ) otherwise). – There is a legal execution E of P with a set of observable behaviours O such ory Model. In our work, we use a weakened version of the memory model that The JMM also defines thread spawn and join action kinds. We omit these for that B = Ext( O ) , or B = Ext( O ) ∪ { hang } and E is hung. By writing t ≤ t � we mean that t is a prefix of t � , set ( t ) is the set of elements of we suggested in [5] and which permits more transformations than the original seen by a read simplicity. – There is a set O such that B = Ext( O ) ∪ { hang } , and for all n ≥ | O | there version. In Tbl. 1, we label this version by ‘JMM-Alt’. the list t , ι ( t, a ) is an index i such that t i = a , or 0 if a / ∈ set ( t ). For an action r1==r2==1? r1==r2==1? must be a legal execution E of P with set of actions A , and a set of actions kind-value pair p = � k, v � we will use the notation π K ( p ) for the action kind k O � such that (i) O and O � are observable behaviours of E , (ii) O ⊆ O � ⊆ A , Definition 8. A well-formed execution � A, P, ≤ po , ≤ so , W, V � with happens be- and π V ( p ) for the value v . We say that a sequence s of action kind-value pairs fore order ≤ hb is legal if there is a finite sequence of sets of actions C i and (iii) n ≤ | O � | , and (iv) Ext( O � ) = Ext( O ) . is sequentially valid with respect to a program P if t ∈ P . A sequentially valid well-formed executions E i = � A i , P, ≤ po i , ≤ so i , W i , V i � with happens-before ≤ hb i trace t is finished for P if there is no sequentially valid trace t � > t . The operator and synchronises-with < sw i such that C 0 = ∅ , C i − 1 ⊆ C i for all i > 0 , � C i = A , ‣ described (in)formally by a set of ‣ described (in)formally by a set of + + stands for trace concatenation. B Proof and for each i > 0 the following rules are satisfied: To establish reasonable properties of concurrent programs we assume reason- 1. C i ⊆ A i . able properties of the underlying sequential language: We prove validity of irrelevant read elimination, elimination of redundant write 2. For all reads r ∈ C i we have W ( r ) ≤ hb r ⇐ ⇒ W ( r ) ≤ hb i r , and r �≤ hb i before write, elimination of redundant read after write, and reordering of non- Definition 6. We say that program P is well-formed if sequential validity of W ( r ) , volatile memory accesses to di ff erent variables. trace t in P implies: axioms and litmus tests axioms and litmus tests 3. V i | C i = V | C i . 1. any trace t � ≤ t is sequentially valid (prefix closedness), 4. W i | C i − 1 = W | C i − 1 . 2. if the last action of t is a read with value v , then the trace obtained from t by replacing the value in the last action by v � is also sequentially valid in P (final read value independence), ‣ hard to design and reason about 2
Introduction On Validity of Program Transformations in the Java Memory Model 47 J. ˇ 46 Sevˇ c´ ık and D. Aspinall 5. For all reads r ∈ A i − C i − 1 we have W i ( r ) ≤ hb i r . 6. For all reads r ∈ C i − C i − 1 we have W ( r ) ∈ C i − 1 . 3. | t | > 0 implies π K (() t 0 ) = St (start action first), 7. If y ∈ C i is an external action and x ≤ hb y then x ∈ C i . 4. π K (() t i ) = Fin implies i = | t | − 1 (finish action last). On Validity of Program Transformations in the Java Memory Model 45 5. θ = θ init implies ∀ i. 1 ≤ i < | t | − 1 → ∃ v. π K (() t i ) = Wr( v ) ∨ π K (() t i ) = The original definition of legality from [11,18] di ff ers in rules 2 and 6, and adds Wr v ( v ) and π K (() t | t | − 1 ) = Fin (initialisation thread only contains writes). Definition 2. An execution E is a tuple E = � A, P, ≤ po , ≤ so , W, V � , where rule 8: A ⊆ A is a set of actions; P is a program, represented as a thread-indexed set of The well-formedness of programs should not be hard to establish for any rea- 2. ≤ hb i | C i = ≤ hb | C i . memory traces; the partial order ≤ po ⊆ A × A is the program order, which is a sonable sequential language. 6. For all reads r ∈ C i − C i − 1 we have W ( r ) ∈ C i − 1 and W i ( r ) ∈ C i − 1 . union of total orders on actions of each thread; ≤ so ⊆ A × A is the synchronisation The next definition places some sensible restriction on executions. 8. If x < ssw i y ≤ hb i z and z ∈ C i − C i − 1 , then x < sw j y for all j ≥ i , where order, which is a total order on all synchronisation actions in A ; V :: A ⇒ V is < ssw i is the transitive reduction of ≤ hb i without any ≤ po i edges, and the a value-written function that assigns a value to each write from A ; W :: A ⇒ A Definition 7. We say that an execution � A, P, ≤ po , ≤ so , W, V � is well-formed transitive reduction of ≤ hb i is a minimum relation such that its transitive is a write-seen function that assigns a write to each read action from A , the if closure is ≤ hb i . W ( r ) denotes the write seen by r , i.e. the value read by r is V ( W ( r )) . x = 0, y = 0, y = 0 memory model 1. A is finite. The reasons for weakening the rules are invalidity of reordering of independent Definition 3. In an execution with synchronisation order ≤ so , an action a 2. ≤ po restricted on actions of one thread is a total order, ≤ po does not relate statements, broken JMM causality tests 17–20 [21], and redundancy. For details, A JMM Definitions synchronises-with an action b (written a < sw b ) if a ≤ so b and a and b sat- actions of di ff erent threads. see [5,6]. isfy one of the following conditions: 3. ≤ so is total on synchronisation actions of A . For reasoning about validity of reordering, we define observable behaviours of The following definitions are mostly from [11,18]; however, we have weakened 4. ≤ so is consistent with ≤ po . – a is an unlock on monitor m and b is a lock on monitor m , executions and programs. Intuitively, a program P has an observable behaviour the definition of execution legality as suggested in [5]. We use letters θ for thread 5. W is properly typed: for every non-volatile read r ∈ A , W ( r ) is a non-volatile – a is a volatile write to v and b is a volatile read from v . B if B is a subset of external actions of some execution of P , and B is downward names, m for synchronisation monitor names, and v for variables (i.e., memory ‣ contract between programmer write; for every volatile read r ∈ A , W ( r ) is a volatile write. closed on happens-before order (restricted to external actions). The JMM cap- locations, in examples, x , y , v etc.). The abstract type V will denote values. r1 = x r2 = y 6. Locking is proper: for all lock actions l ∈ A on monitors m and all threads θ Definition 4. The happens-before order of an execution is the transitive closure tures non-termination as a behaviour in the definition of allowable behaviours. The starting point is the notion of action . di ff erent from the thread of l , the number of locks in θ before l in ≤ so is the of the composition of its synchronises-with order and its program order, i.e. ≤ hb = ( < sw ∪ ≤ po ) + . same as the number of unlocks in θ before l in ≤ so . Definition 1. An action is a memory-related operation; it is modelled by an Definition 9. An execution � A, P, ≤ po , ≤ so , W, V � with happens-before order 7. Program order is intra-thread consistent: for each thread θ , the trace of θ in abstract type A with the following properties: (1) Each action belongs to one ≤ hb has a set of observable behaviours O if for all x ∈ O we have y ≤ hb x To relate a (sequential) program to a sequence of actions performed by one thread, we will denote it by T ( a ) . (2) An action is one of the following action E is sequentially valid for P θ . and programming environment or y ≤ so x implies y ∈ O or T ( y ) = θ init . Moreover, there is no x ∈ O such that thread we must define a notion of sequential validity . We consider single-thread kinds : 8. ≤ so is consistent with W : for every volatile read r of a variable v we have T ( x ) = θ init . programs as sets of sequences of pairs of an action kind and a value, which we W ( r ) ≤ so r and for any volatile write w to v , either w ≤ so W ( r ) or r ≤ so w . y = 1 x = 1 – volatile read of v , – normal write to v , call traces . A multi-thread program is a set of single-thread programs indexed – thread start , 9. ≤ hb is consistent with W : for all reads r of v it holds that r �≤ hb W ( r ) and The allowable behaviours may contain a special external hang action if the ex- – volatile write to v , – lock on m , by thread identifiers. – thread finish , there is no intervening write w to v , i.e. if W ( r ) ≤ hb w ≤ hb r and w writes ecution does not terminate. We will use the notation Ext( A )) for all external – normal read from v , – unlock on m , – external action . to v then W ( r ) = w . actions of set A , i.e., Ext( A ) = { a | K ( a ) = Ex } . Definition 5. Given an execution E = � A, P, ≤ po , ≤ so , W, V � , the action trace ‣ specifies which writes can be We denote the action kind of a by K ( a ) , the action kinds will be abbreviated to 10. The initialisation thread θ init finishes before any other thread starts, i.e., of thread θ in E , denoted Tr E ( θ ) , is the list of actions of thread θ in the order Definition 10. A finite set of actions B is an allowable behaviour of a program Rd v ( v ) , Wr v ( v ) , Rd( v ) , Wr( v ) , L( m ) , U( m ) , St , Fin , Ex . An action kind also ∀ a, b ∈ A. K ( a ) = Fin ∧ T ( a ) = θ init ∧ K ( b ) = St ∧ T ( b ) � = θ init → a ≤ so b . ≤ po . The trace of thread θ in E , written Tr E ( θ ) is the list of action kinds and includes the associated variable or monitor. The volatile read, volatile write, lock, P if either corresponding values obtained from the action trace (i.e., V ( W ( a )) if a is a read, The following definition of legal execution constitutes the core of the Java Mem- unlock, start, finish actions are called synchronisation actions . V ( a ) otherwise). – There is a legal execution E of P with a set of observable behaviours O such ory Model. In our work, we use a weakened version of the memory model that The JMM also defines thread spawn and join action kinds. We omit these for that B = Ext( O ) , or B = Ext( O ) ∪ { hang } and E is hung. By writing t ≤ t � we mean that t is a prefix of t � , set ( t ) is the set of elements of we suggested in [5] and which permits more transformations than the original seen by a read simplicity. – There is a set O such that B = Ext( O ) ∪ { hang } , and for all n ≥ | O | there version. In Tbl. 1, we label this version by ‘JMM-Alt’. the list t , ι ( t, a ) is an index i such that t i = a , or 0 if a / ∈ set ( t ). For an action r1==r2==1? r1==r2==1? must be a legal execution E of P with set of actions A , and a set of actions kind-value pair p = � k, v � we will use the notation π K ( p ) for the action kind k O � such that (i) O and O � are observable behaviours of E , (ii) O ⊆ O � ⊆ A , Definition 8. A well-formed execution � A, P, ≤ po , ≤ so , W, V � with happens be- and π V ( p ) for the value v . We say that a sequence s of action kind-value pairs fore order ≤ hb is legal if there is a finite sequence of sets of actions C i and (iii) n ≤ | O � | , and (iv) Ext( O � ) = Ext( O ) . is sequentially valid with respect to a program P if t ∈ P . A sequentially valid well-formed executions E i = � A i , P, ≤ po i , ≤ so i , W i , V i � with happens-before ≤ hb i trace t is finished for P if there is no sequentially valid trace t � > t . The operator and synchronises-with < sw i such that C 0 = ∅ , C i − 1 ⊆ C i for all i > 0 , � C i = A , ‣ described (in)formally by a set of ‣ described (in)formally by a set of + + stands for trace concatenation. B Proof and for each i > 0 the following rules are satisfied: To establish reasonable properties of concurrent programs we assume reason- 1. C i ⊆ A i . able properties of the underlying sequential language: We prove validity of irrelevant read elimination, elimination of redundant write 2. For all reads r ∈ C i we have W ( r ) ≤ hb r ⇐ ⇒ W ( r ) ≤ hb i r , and r �≤ hb i before write, elimination of redundant read after write, and reordering of non- Definition 6. We say that program P is well-formed if sequential validity of W ( r ) , volatile memory accesses to di ff erent variables. trace t in P implies: axioms and litmus tests axioms and litmus tests 3. V i | C i = V | C i . 1. any trace t � ≤ t is sequentially valid (prefix closedness), 4. W i | C i − 1 = W | C i − 1 . 2. if the last action of t is a read with value v , then the trace obtained from t by replacing the value in the last action by v � is also sequentially valid in P (final read value independence), ‣ hard to design and reason about ‣ hard to design and reason about 2
MemSAT overview litmus test legality witness MemSAT Mem memory model proof of illegality finitization parameters 3
MemSAT overview annotated java program with one or more assertions P legality witness MemSAT Mem memory model proof of illegality finitization parameters 3
MemSAT overview annotated java program with one or more assertions P legality witness MemSAT Mem M proof of illegality set of constraints finitization in relational logic parameters 3
MemSAT overview annotated java program with one ‣ translate P to relational logic or more assertions ‣ combine result with M ‣ solve combined constraints P legality witness MemSAT F(P, M) M proof of illegality set of constraints finitization in relational logic parameters 3
MemSAT overview annotated java program with one ‣ translate P to relational logic or more assertions ‣ combine result with M ‣ solve combined constraints P legality witness F(P, M) M proof of illegality kodkod set of constraints finitization in relational logic parameters 3
MemSAT overview annotated java model (solution) of program with one the legality formula ‣ translate P to relational logic or more assertions ‣ combine result with M ‣ solve combined constraints sat P model(F(P, M)) F(P, M) M proof of illegality kodkod set of constraints finitization in relational logic parameters 3
MemSAT overview annotated java model (solution) of program with one the legality formula ‣ translate P to relational logic or more assertions ‣ combine result with M ‣ solve combined constraints sat P model(F(P, M)) F(P, M) unsat M mincore(F(P, M)) kodkod set of constraints minimal unsatisfiable finitization in relational logic core of the legality formula parameters 3
Specifying a litmus test public class Test0 { static int x = 0; static int y = 0; ‣ control flow ‣ synchronize x = 0, y = 0, y = 0 ‣ method calls @thread ‣ field and array accesses public static void thread1() { r1 = x r2 = y ‣ assertions final int r1 = x; y = 1 x = 1 y = 1; assert r1==1; } r1==r2==1? r1==r2==1? @thread public static void thread2() { final int r2 = y; x = 1; assert r2==1; } } 4
Specifying a memory model relational logic constants variables 5
Specifying a memory model first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) bitvector arithmetic (+, -, *, /,) relational logic constants variables 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order logic constants variables 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order logic constants variables x = 0, y = 0, y = 0 r1 = x r2 = y y = 1 x = 1 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order logic constants variables x = 0, y = 0, y = 0 t0 r1 = x r2 = y y = 1 x = 1 t1 t2 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants variables x = 0, y = 0, y = 0 t0 r1 = x r2 = y y = 1 x = 1 t1 t2 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants variables relational variables capture runtime properties of a program x = 0, y = 0, y = 0 t0 ‣ A, set of all executed actions ‣ W, maps reads to seen writes r1 = x r2 = y ‣ V, maps writes to written values y = 1 x = 1 ‣ l, maps reads/writes to locations t1 t2 ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions ‣ W, maps reads to seen writes r1 = x r2 = y ‣ V, maps writes to written values y = 1 x = 1 ‣ l, maps reads/writes to locations t1 t2 ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions a10: start ‣ W, maps reads to seen writes r1 = x r2 = y a11: read(x, 0) ‣ V, maps writes to written values a12: write(y, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations t2 a13: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions a10: start a20: start ‣ W, maps reads to seen writes r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations a13: end a23: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions A = { 〈 a00 〉 , 〈 a01 〉 , ..., 〈 a23 〉 } a10: start a20: start ‣ W, maps reads to seen writes r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations a13: end a23: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions A = { 〈 a00 〉 , 〈 a01 〉 , ..., 〈 a23 〉 } a10: start a20: start ‣ W, maps reads to seen writes W = { 〈 a11, a01 〉 , 〈 a21, a12 〉 } r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations a13: end a23: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions A = { 〈 a00 〉 , 〈 a01 〉 , ..., 〈 a23 〉 } a10: start a20: start ‣ W, maps reads to seen writes W = { 〈 a11, a01 〉 , 〈 a21, a12 〉 } r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values V = { 〈 a01, 0 〉 , 〈 a02, 0 〉 , 〈 a12, 1 〉 , 〈 a22, 1 〉 } a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations a13: end a23: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions A = { 〈 a00 〉 , 〈 a01 〉 , ..., 〈 a23 〉 } a10: start a20: start ‣ W, maps reads to seen writes W = { 〈 a11, a01 〉 , 〈 a21, a12 〉 } r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values V = { 〈 a01, 0 〉 , 〈 a02, 0 〉 , 〈 a12, 1 〉 , 〈 a22, 1 〉 } a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations l = { 〈 a01, x 〉 , 〈 a02, y 〉 , ..., 〈 a22, x 〉 } a13: end a23: end ‣ m, maps locks/unlocks to monitors 5
Specifying a memory model relational constants capture first order logic ( ∀ , ∃ , ∧ , ∨ , ¬ ) static properties of a program relational algebra (., ∪ , ∩ , ∕ , × , ⊆ ) ‣ co, control flow bitvector arithmetic (+, -, *, /,) relational ‣ to, thread order to = { 〈 t0, t1 〉 , 〈 t0, t2 〉 } logic constants a00: start variables a01: write(x, 0) relational variables capture runtime a02: write(y, 0) properties of a program x = 0, y = 0, y = 0 a03: end ‣ A, set of all executed actions A = { 〈 a00 〉 , 〈 a01 〉 , ..., 〈 a23 〉 } a10: start a20: start ‣ W, maps reads to seen writes W = { 〈 a11, a01 〉 , 〈 a21, a12 〉 } r1 = x r2 = y a11: read(x, 0) a21: read(y, 1) ‣ V, maps writes to written values V = { 〈 a01, 0 〉 , 〈 a02, 0 〉 , 〈 a12, 1 〉 , 〈 a22, 1 〉 } a12: write(y, 1) a22: write(x, 1) y = 1 x = 1 ‣ l, maps reads/writes to locations l = { 〈 a01, x 〉 , 〈 a02, y 〉 , ..., 〈 a22, x 〉 } a13: end a23: end ‣ m, maps locks/unlocks to monitors m = { } 5
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: sequential consistency interleaved semantics all statements appear to execute in a total order that agrees with the program text 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] Execution order is total, 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] antisymmetric, and 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] transitive. 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] It respects the control flow and 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] thread order. 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] Reads cannot see out of order writes. 7. ∀ k: A ∩ Read, j: A ∩ Write | No write interferes between a read and the write seen by that read. ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) 6
Example: Java memory model committing semantics an execution is legal if it can be derived by committing and executing actions in a sequence of speculative executions A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model initial execution: reads can only see writes that committing semantics happen-before them an execution is legal if it can be derived by A 1 committing and executing actions in a sequence of speculative executions A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model initial execution: reads can only see writes that committing semantics happen-before them an execution is legal if it can be derived by A 1 committing and executing actions in a sequence of speculative executions C 1 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model i th execution: committed reads can see committed writes; other reads must committing semantics see writes that happen- A 2 an execution is legal if it can be derived by before them committing and executing actions in a sequence of speculative executions C 1 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model i th execution: committed reads can see committed writes; other reads must committing semantics see writes that happen- A 2 an execution is legal if it can be derived by before them committing and executing actions in a sequence of speculative executions C 1 C 2 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model i th execution: committed reads can see committed writes; other reads must A k committing semantics see writes that happen- an execution is legal if it can be derived by before them committing and executing actions in a sequence of speculative executions C 1 C 2 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model i th execution: committed reads can see committed writes; other reads must A k committing semantics see writes that happen- an execution is legal if it can be derived by before them committing and executing actions in a sequence of speculative executions … C k C 1 C 2 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Example: Java memory model committing semantics an execution is legal if it can be derived by committing and executing actions in a sequence of speculative executions … C k C 1 C 2 A 1. ∀ i: [1..k] | C i ⊆ A i 2. ∀ i: [1..k], r: C i ∩ Read | (hb[W[r], r] ⇔ hb i [W[r], r]) ∧ ¬ hb i [r, W[r]] … ⇝ … ⇝ E 1 ⇝ E 2 E k E 3. ∀ i: [1..k] | C i ◁ V i = C i ◁ V 4. ∀ i: [1..k] | C i-1 ◁ W i = C i-1 ◁ W A 1 , W 1 , V 1 , A 2 , W 2 , V 2 , A k , W k , V k , A, W, V, l 1 , m 1 , l 2 , m 2 , l k , m k , l, m, 5. ∀ i: [1..k], r: (A i ⧵ C i ) ∩ Read | hb i [W i [r], r] po 1 , so 1 , po 2 , so 2 , po k , so k , po, so, 6. ∀ i: [1..k], r: (C i ⧵ C i-1 ) ∩ Read | W i [r] ⊆ C i-1 sw 1 , hb 1 sw 2 , hb 2 sw k , hb k sw, hb 7. ∀ i: [1..k], y: C i , x: A i | (y ⊆ Special ∧ hb[x, y]) ⇒ x ⊆ C i-1 7
Witness of legality (model) E 1 E 2 E a00: start a00: start a00: start a01: write(x, 0) a01: write(x, 0) a01: write(x, 0) a02: write(y, 0) a02: write(y, 0) a02: write(y, 0) a03: end a03: end a03: end W 2 W 1 hb 2 hb 1 hb a10: start a20: start a10: start a20: start a10: start a20: start W a11: read(x, 0) a21: read(y, 0) a11: read(x, 0) a21: read(y, 0) a11: read(x, 1) a21: read(y, 1) a12: write(y, 1) a22: write(x, 1) a12: write(y, 1) C 1 a22: write(x, 1) a12: write(y, 1) a22: write(x, 1) C 2 a13: end a23: end a13: end a23: end a13: end a23: end x = 0, y = 0, y = 0 witness: an execution of the r1 = x r2 = y program that satisfies both the y = 1 x = 1 JMM assertions and the memory model constraints. r1==r2==1? r1==r2==1? 8
Proof of illegality (minimal core) V[a 01 ] = 0 x = 0, y = 0, y = 0 V[a 02 ] = 0 r1 = x r2 = y V[W[a 11 ]] = 1 y = 1 x = 1 V[W[a 21 ]] = 1 r1==1 && r2==1? r1==1 && ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) a ij represents the action (if V[a 01 ] = 0 x = 0, y = 0, y = 0 any) performed by the j th V[a 02 ] = 0 statement of the i th thread r1 = x r2 = y V[W[a 11 ]] = 1 y = 1 x = 1 V[W[a 21 ]] = 1 r1==1 && r1==1 && r2==1? ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) V[a 01 ] = 0 x = 0, y = 0, y = 0 V[a 02 ] = 0 r1 = x r2 = y V[W[a 11 ]] = 1 y = 1 x = 1 V[W[a 21 ]] = 1 r1==1 && r2==1? r1==1 && ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) V[a 01 ] = 0 x = 0, y = 0, y = 0 V[a 02 ] = 0 r1 = x r2 = y V[W[a 11 ]] = 1 y = 1 x = 1 V[W[a 21 ]] = 1 r1==1 && r2==1? r1==1 && ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) ✄ V[a 01 ] = 0 a01: write(x, 1) x = 1, x = 0, y = 0, y = 0 V[a 02 ] = 0 a02: write(y, 0) r1 = x r2 = y a11: read(x, 1) V[W[a 11 ]] = 1 y = 1 x = 1 a12: write(y, 1) V[W[a 21 ]] = 1 a21: read(y, 1) r1==1 && r1==1 && r2==1? a22: write(x, 1) ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) V[a 01 ] = 0 a01: write(x, 0) a01: write(x, 1) x = 0, y = 0, y = 0 V[a 02 ] = 0 a02: write(y, 0) a02: write(y, 0) r1 = x r2 = y a11: read(x, 0) a11: read(x, 1) ✄ V[W[a 11 ]] = 1 y = 1 x = 1 a12: write(y, 1) a12: write(y, 1) V[W[a 21 ]] = 1 a21: read(y, 1) a21: read(y, 1) r1==1 && r1==1 && r2==1? a22: write(x, 1) a22: write(x, 1) ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Proof of illegality (minimal core) V[a 01 ] = 0 a01: write(x, 0) a01: write(x, 0) a01: write(x, 1) x = 0, y = 0, y = 0 V[a 02 ] = 0 a02: write(y, 0) a02: write(y, 0) a02: write(y, 0) r1 = x r2 = y a11: read(x, 0) a11: read(x, 1) a12: write(y, 1) V[W[a 11 ]] = 1 y = 1 x = 1 a12: write(y, 1) a12: write(y, 1) a21: read(y, 1) V[W[a 21 ]] = 1 a22: write(x, 1) a21: read(y, 1) a21: read(y, 1) r1==1 && r2==1? r1==1 && a22: write(x, 1) a22: write(x, 1) a11: read(x, 1) ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] SC 1. ∀ i, j: A | i ≠ j ⇒ ord[i, j] ∨ ord[j, i] ✄ ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 2. ∀ i, j: A | ord[i, j] ⇒ ¬ord[j, i] ∀ k: A ∩ Read | ¬ ord[k, W[k]] 3. ∀ i, j, k: A | (ord[i, j] ∧ ord[j, k]) ⇒ ord[i, k] 4. ∀ i, j: A | (t[i] = t[j] ∧ co + [i, j]) ⇒ ord[i, j] 5. ∀ i, j: A | (t[i] ≠ t[j] ∧ to + [t[i], t[j]]) ⇒ ord[i, j] minimal core: an unsatisfiable 6. ∀ k: A ∩ Read | ¬ ord[k, W[k]] subset of the program and 7. ∀ k: A ∩ Read, j: A ∩ Write | memory model constraints that ¬ ( l[k] = l[j] ∧ ord[W[k], j] ∧ ord[j, k] ) becomes satisfiable if one of its members is removed 9
Approach Program preprocessor translator finitization parameters Memory constraint bounds model assembler assembler solver 10
Approach finitize P and convert it to an intermediate form I(P) Program preprocessor translator finitization parameters Memory constraint bounds model assembler assembler solver 10
Approach finitize P and translate I(P) to convert it to an a relational intermediate form representation I(P) Program preprocessor translator R(P) finitization parameters Memory constraint bounds model assembler assembler solver 10
Approach finitize P and translate I(P) to convert it to an a relational intermediate form representation I(P) Program preprocessor translator R(P) finitization parameters F(P, M) Memory constraint bounds model assembler assembler combine R(P) and M into the legality formula solver 10
Approach finitize P and translate I(P) to convert it to an a relational intermediate form representation I(P) Program preprocessor translator compute a set of R(P) bounds on the finitization search space parameters F(P, M) Memory constraint bounds model assembler assembler combine R(P) B(P, M) and M into the legality formula solver 10
Approach WALA MemSAT Program preprocessor translator contributions y t i r a l u d finitization o m parameters efficiency Memory constraint bounds model assembler assembler kodkod + MiniSat 10
Preprocessing public class Test1 { public class Test1 { static int x = 0; static int x = 0; static int y = 0; static int y = 0; @thread @thread finitize P and public static void thread1() { public static void thread1() { convert it to an final int r1 = x; final int r1 = x; intermediate form if ( r1 != 0) if ( r1 != 0) I(P) y = r1; y = r1; else else y = 1; y = 1; assert r1==1; assert r1==1; } } @thread @thread public static void thread2() { public static void thread2() { final int r2 = y; final int r2 = y; x = 1; x = 1; assert r2==1; assert r2==1; } } } } 11
Preprocessing public class Test1 { public class Test1 { 00 start static int x = 0; static int x = 0; static int y = 0; static int y = 0; 01 write(x, 0) @thread @thread 02 write(y, 0) public static void thread1() { public static void thread1() { final int r1 = x; final int r1 = x; 03 end if ( r1 != 0) if ( r1 != 0) y = r1; y = r1; else else 10 start 20 start y = 1; y = 1; assert r1==1; assert r1==1; 11 r1=read(x) 21 r2=read(y) } } 12 branch(r1!=0) T F @thread @thread 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) public static void thread2() { public static void thread2() { final int r2 = y; final int r2 = y; 15 assert(r1==1) 23 assert(r2==1) x = 1; x = 1; assert r2==1; assert r2==1; 16 end 24 end } } } } 11
Preprocessing public class Test1 { public class Test1 { 00 start static int x = 0; static int x = 0; control flow static int y = 0; static int y = 0; 01 write(x, 0) @thread @thread 02 write(y, 0) public static void thread1() { public static void thread1() { final int r1 = x; final int r1 = x; 03 end thread order if ( r1 != 0) if ( r1 != 0) y = r1; y = r1; else else 10 start 20 start y = 1; y = 1; assert r1==1; assert r1==1; 11 r1=read(x) 21 r2=read(y) } } 12 branch(r1!=0) T F @thread @thread 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) public static void thread2() { public static void thread2() { final int r2 = y; final int r2 = y; 15 assert(r1==1) 23 assert(r2==1) x = 1; x = 1; assert r2==1; assert r2==1; 16 end 24 end } } } } 11
Preprocessing public class Test1 { public class Test1 { s guard 00 start static int x = 0; static int x = 0; 13 r1!=0 static int y = 0; static int y = 0; 14 r1==0 01 write(x, 0) * true @thread @thread 02 write(y, 0) public static void thread1() { public static void thread1() { final int r1 = x; final int r1 = x; 03 end if ( r1 != 0) if ( r1 != 0) y = r1; y = r1; else else 10 start 20 start y = 1; y = 1; assert r1==1; assert r1==1; 11 r1=read(x) 21 r2=read(y) } } 12 branch(r1!=0) T F @thread @thread 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) public static void thread2() { public static void thread2() { final int r2 = y; final int r2 = y; 15 assert(r1==1) 23 assert(r2==1) x = 1; x = 1; assert r2==1; assert r2==1; 16 end 24 end } } } } 11
Preprocessing public class Test1 { public class Test1 { s guard 00 start static int x = 0; static int x = 0; 13 r1!=0 static int y = 0; static int y = 0; 14 r1==0 01 write(x, 0) * true @thread @thread 02 write(y, 0) s maySee public static void thread1() { public static void thread1() { 11 { 01 , 22 } final int r1 = x; final int r1 = x; 03 end 21 { 02 , 13 , 14 } if ( r1 != 0) if ( r1 != 0) y = r1; y = r1; else else 10 start 20 start y = 1; y = 1; assert r1==1; assert r1==1; 11 r1=read(x) 21 r2=read(y) } } 12 branch(r1!=0) T F @thread @thread 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) public static void thread2() { public static void thread2() { final int r2 = y; final int r2 = y; 15 assert(r1==1) 23 assert(r2==1) x = 1; x = 1; assert r2==1; assert r2==1; 16 end 24 end } } } } 11
Translation s guard 00 start 13 r1!=0 14 r1==0 01 write(x, 0) * true 02 write(y, 0) s maySee translate I(P) to a 11 relational { 01 , 22 } 03 end 21 { 02 , 13 , 14 } representation R(P) 10 start 20 start 11 r1=read(x) 21 r2=read(y) 12 branch(r1!=0) T F 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) 15 assert(r1==1) 23 assert(r2==1) 16 end 24 end 12
Translation s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation maps reads, writes, locks, and unlocks to relations representing locations that are accessed s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation maps reads, writes, locks, and unlocks to relations representing locations that are accessed s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } relational constants 03 end 03 ⊤ 21 { 02 , 13 , 14 } that represent fields: 10 ⊤ x = {< x >} and y = 11 x ⊤ {< y >} 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation maps writes and asserts to relational encodings of the values written or asserted s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation maps writes and asserts to relational encodings of the values written or asserted s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 ⊤ relational variable 11 x ⊤ that acts as a 12 ⊤ 10 start 20 start placeholder for the 13 y r1 r1 ≠ Bits(0) value read into r1 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation maps statements to formulas that encode their guards s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 02 write(y, 0) 01 x Bits(0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Translation s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee 02 y Bits(0) ⊤ 11 { 01 , 22 } 03 03 end ⊤ 21 { 02 , 13 , 14 } 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) ⊤ 21 r2=read(y) 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 12
Constraint assembly s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee construct the 02 y Bits(0) ⊤ 11 legality formula { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } for R(P) and M F(P, M) 10 ⊤ 11 x ⊤ 12 ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee 02 y Bits(0) F(R(P), E) ∧ ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start The witness execution E 13 r1!=0 respects the sequential s Loc Val Guard 14 r1==0 01 write(x, 0) semantics of P 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee 02 y Bits(0) F(R(P), E) ∧ ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start The witness execution E 13 r1!=0 respects the sequential s Loc Val Guard 14 r1==0 01 write(x, 0) semantics of P 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee E executes and 02 y Bits(0) F(R(P), E) ∧ ⊤ 11 satisfies the { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } assertions in P 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start The witness execution E 13 r1!=0 respects the sequential s Loc Val Guard 14 r1==0 01 write(x, 0) semantics of P 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee E executes and 02 y Bits(0) F(R(P), E) ∧ ⊤ 11 satisfies the { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } assertions in P 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ Each speculative ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) execution E i respects 14 y Bits(1) r1 =Bits(0) the sequential M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) semantics of P 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start The witness execution E 13 r1!=0 respects the sequential s Loc Val Guard 14 r1==0 01 write(x, 0) semantics of P 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee E executes and 02 y Bits(0) F(R(P), E) ∧ ⊤ 11 satisfies the { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } assertions in P 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ Each speculative ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) execution E i respects 14 y Bits(1) r1 =Bits(0) the sequential M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) semantics of P 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) E and all E i respect the ⊤ 22 x Bits(1) memory model constraints ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly s guard 00 start 13 r1!=0 s Loc Val Guard 14 r1==0 01 write(x, 0) 00 * true ⊤ 01 x Bits(0) 02 write(y, 0) ⊤ s maySee 02 y Bits(0) F(R(P), E) ∧ F(R(P), E) ∧ ⊤ 11 { 01 , 22 } 03 end 03 ⊤ 21 { 02 , 13 , 14 } 10 F α (R(P), E) ∧ F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 10 start 20 start 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) M(E, E 1 , … , E k ) M(E, E 1 , … , E k ) 11 r1=read(x) 15 r1 =Bits(1) 21 r2=read(y) ⊤ 12 branch(r1!=0) 16 ⊤ 20 T F ⊤ 21 y 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 15 assert(r1==1) 23 assert(r2==1) 24 ⊤ 16 end 24 end 13
Constraint assembly: F α (R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 ⊤ 01 x Bits(0) ⊤ 02 y Bits(0) F(R(P), E) ∧ ⊤ 03 ⊤ 10 F α (R(P), E) ∧ ⊤ 11 x ⊤ 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 13 y r1 r1 ≠ Bits(0) 14 y Bits(1) r1 =Bits(0) M(E, E 1 , … , E k ) 15 r1 =Bits(1) ⊤ 16 ⊤ 20 ⊤ 21 y ⊤ 22 x Bits(1) ⊤ 23 r2 =Bits(1) ⊤ 24 ⊤ 14
Constraint assembly: F α (R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⊤ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ ⊤ 11 r1=read(x) 11 x a 11 ⊤ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 M(E, E 1 , … , E k ) relational variable a ij 15 assert(r1==1) 15 r1 =Bits(1) ⊤ represents the action 16 end 16 a 16 ⊤ performed if E executes 20 start 20 a 20 ⊤ the statement ij 21 r2=read(y) 21 y a 21 ⊤ 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ 14
Constraint assembly: F α (R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⊤ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ ⊤ V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ ⊤ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 M(E, E 1 , … , E k ) 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ⊤ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 14
Constraint assembly: F α (R(P), E) s Loc Val Guard 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⊤ 03 end 03 a 03 ⊤ 10 start 10 a 10 V [ W [ a 11 ]]=Bits(1) ∧ F α (R(P), E) ∧ ⊤ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , … , E k ) 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ⊤ M(E, E 1 , …, E k ) 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 14
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ ‣ 0 or 1 action performed | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ ‣ action performed iff the A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ guard is true 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ ‣ no other statement (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 performs the same action (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ ‣ action location is valid l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ ‣ 0 or 1 action performed | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ ‣ action performed iff the A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ guard is true 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ ‣ no other statement (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 performs the same action (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ ‣ action location is valid l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 V [ W [ a 11 ]]=Bits(1) ∧ F α (R(P), E) ∧ ( | a 13 | = 1 ⇔ ⊤ ‣ action performed iff the A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ guard is true 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ ‣ no other statement (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 performs the same action (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ ‣ action location is valid l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ ‣ no other statement (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 performs the same action (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ ‣ action location is valid l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ ‣ action location is valid l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 ‣ action value is valid V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Constraint assembly: F(R(P), E) A set of all executed actions W maps reads to seen writes V maps writes to written values l maps writes to written values s Loc Val Guard m maps locks/unlocks to monitors 00 start 00 a 00 ⊤ 01 write(x, 0) 01 x Bits(0) a 01 ⊤ 02 write(y, 0) 02 y Bits(0) a 02 F(R(P), E) ∧ ⋀ s ∈ P F(s, R(P), E) ∧ ⊤ | a 13 | ≤ 1 ∧ 03 end 03 a 03 ⊤ 10 start 10 a 10 F α (R(P), E) ∧ V [ W [ a 11 ]]=Bits(1) ∧ ( | a 13 | = 1 ⇔ ⊤ A = a 00 ∪ … ∪ a 24 ∧ V [ W [ a 11 ]] V [ W [ a 11 ]] 11 r1=read(x) 11 x a 11 ⊤ V[W[a 11 ]] ≠ Bits(0)) ∧ 12 branch(r1!=0) 12 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ V [ W [ a 21 ]]=Bits(1) ∧ ⊤ V [ W [ a 11 ]]=Bits(1) ∧ (a 13 ∩ a 00 ) = ∅ ∧ … ∧ 13 write(y, r1) 13 y r1 r1 ≠ Bits(0) a 13 (a 13 ∩ a 24 ) = ∅ ∧ 14 write(y, 1) 14 y Bits(1) r1 =Bits(0) a 14 ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ M(E, E 1 , …, E k ) V [ W [ a 21 ]]=Bits(1) ∧ l[a 13 ] = y ∧ 15 assert(r1==1) 15 r1 =Bits(1) ⊤ 16 end 16 a 16 V[a 13 ] = V[W[a 11 ]] ⊤ M(E, E 1 , …, E k ) ⋀ 1 ≤ i ≤ k F(R(P), E i ) ∧ 20 start 20 a 20 ⊤ 21 r2=read(y) 21 y a 21 ⊤ M(E, E 1 , … , E k ) 22 write(x, 1) 22 x Bits(1) a 22 ⊤ 23 assert(r2==1) 23 r2 =Bits(1) ⊤ 24 end 24 a 24 ⊤ V [ W [ a 21 ]] 15
Bounds assembly s guard 00 start 13 r1!=0 14 r1==0 01 write(x, 0) * true 02 write(y, 0) s maySee compute a set of 11 bounds on the { 01 , 22 } 03 end 21 { 02 , 13 , 14 } search space B(P, M) F(P, M) 10 start 20 start 11 r1=read(x) 21 r2=read(y) 12 branch(r1!=0) T F 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) 15 assert(r1==1) 23 assert(r2==1) 16 end 24 end 16
Bounds assembly s guard 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 02 write(y, 0) s maySee 11 { 01 , 22 } 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} 10 start 20 start {…} ⊆ V ⊆ {…} 11 r1=read(x) 21 r2=read(y) 12 branch(r1!=0) {…} ⊆ W ⊆ {…} T F 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} 16 end 24 end 16
Bounds assembly: universe s guard 00 start finite universe of -8, 1, 2, 4, x, y, 13 r1!=0 symbolic values from a00, a01, a02, a03, 14 r1==0 01 write(x, 0) which the model, if a10, a11, a13, a16, * true any, is drawn a20, a21, a22, a24 02 write(y, 0) s maySee 11 { 01 , 22 } 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} 10 start 20 start {…} ⊆ V ⊆ {…} 11 r1=read(x) 21 r2=read(y) 12 branch(r1!=0) {…} ⊆ W ⊆ {…} T F 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} 16 end 24 end 17
Bounds assembly: universe primitives fields s guard 00 start finite universe of -8, 1, 2, 4, x, y, 13 r1!=0 symbolic values from a00, a01, a02, a03, 14 r1==0 01 write(x, 0) which the model, if a10, a11, a13, a16, * true any, is drawn a20, a21, a22, a24 02 write(y, 0) s maySee 11 { 01 , 22 } 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} 10 start 20 start {…} ⊆ V ⊆ {…} 11 r1=read(x) 21 r2=read(y) 12 branch(r1!=0) {…} ⊆ W ⊆ {…} T F 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} 16 end 24 end 17
Bounds assembly: universe primitives fields s guard a00 00 start finite universe of -8, 1, 2, 4, x, y, 13 r1!=0 symbolic values from a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) which the model, if a10, a11, a13, a16, * true any, is drawn a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } actions a03 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} a10 a20 10 start 20 start {…} ⊆ V ⊆ {…} a11 11 r1=read(x) a21 21 r2=read(y) 12 branch(r1!=0) {…} ⊆ W ⊆ {…} a13 T F a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 17
Bounds assembly: lower/upper bounds s guard a00 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } a03 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} a10 a20 10 start 20 start {…} ⊆ V ⊆ {…} a11 11 r1=read(x) a21 21 r2=read(y) 12 branch(r1!=0) upper and lower {…} ⊆ W ⊆ {…} bound on the value a13 T F of each relation that a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) appears in F(P, M) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 18
Bounds assembly: lower/upper bounds s guard a00 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } a03 03 end 21 { 02 , 13 , 14 } F(P, M) {…} ⊆ A ⊆ {…} a10 a20 10 start 20 start {…} ⊆ V ⊆ {…} a11 11 r1=read(x) a21 21 r2=read(y) 12 branch(r1!=0) upper and lower {…} ⊆ W ⊆ {…} bound on the value a13 T F of each relation that a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) appears in F(P, M) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 18
Bounds assembly: lower/upper bounds s guard a00 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } a03 03 end { } 21 { 02 , 13 , 14 } < a00 >, < a01 >, < a02 >, < a03 >, < a10 >, < a11 >, F(P, M) {…} ⊆ A ⊆ {…} < a13 >, < a16 >, < a20 >, a10 a20 10 start 20 start < a21 >, < a22 >, < a24 > {…} ⊆ V ⊆ {…} a11 11 r1=read(x) a21 21 r2=read(y) 12 branch(r1!=0) upper and lower {…} ⊆ W ⊆ {…} bound on the value a13 T F of each relation that a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) appears in F(P, M) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 18
Bounds assembly: lower/upper bounds s guard a00 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } a03 03 end { } { } 21 { 02 , 13 , 14 } < a00 >, < a01 >, < a02 >, < a00 >, < a01 >, < a02 >, < a03 >, < a10 >, < a11 >, < a03 >, < a10 >, < a11 >, F(P, M) {…} ⊆ A ⊆ {…} < a13 >, < a16 >, < a20 >, < a16 >, < a20 >, a10 a20 10 start 20 start < a21 >, < a22 >, < a24 > < a21 >, < a22 >, < a24 > {…} ⊆ V ⊆ {…} a11 11 r1=read(x) a21 21 r2=read(y) 12 branch(r1!=0) upper and lower {…} ⊆ W ⊆ {…} bound on the value a13 T F of each relation that a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) appears in F(P, M) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 18
Bounds assembly: lower/upper bounds s guard a00 00 start -8, 1, 2, 4, x, y, 13 r1!=0 a00, a01, a02, a03, a01 14 r1==0 01 write(x, 0) a10, a11, a13, a16, * true a20, a21, a22, a24 a02 02 write(y, 0) s maySee 11 { 01 , 22 } a03 03 end { } { } 21 { 02 , 13 , 14 } < a00 >, < a01 >, < a02 >, < a00 >, < a01 >, < a02 >, < a03 >, < a10 >, < a11 >, < a03 >, < a10 >, < a11 >, F(P, M) {…} ⊆ A ⊆ {…} < a13 >, < a16 >, < a20 >, < a16 >, < a20 >, a10 a20 10 start 20 start < a21 >, < a22 >, < a24 > < a21 >, < a22 >, < a24 > {…} ⊆ V ⊆ {…} { < a21 , a13 > } a11 11 r1=read(x) < a11 , a01 >, a21 21 r2=read(y) 12 branch(r1!=0) upper and lower < a11 , a22 >, {…} ⊆ W ⊆ {…} bound on the value < a21 , a02 >, a13 T F of each relation that a22 13 write(y, r1) 14 write(y, 1) 22 write(x, 1) appears in F(P, M) {…} ⊆ l ⊆ {…} 15 assert(r1==1) 23 assert(r2==1) {…} ⊆ m ⊆ {…} a16 a24 16 end 24 end 18
Recommend
More recommend