Mathematizing C++ concurrency Mark Batty, Scott Owens, Susmit Sarkar, Peter Sewell, Tjark Weber University of Cambridge thanks to: Hans Boehm, Lawrence Crowl, Peter Dimov, Doug Lea, Nick Maclaren, Paul McKenney, Clark Nelson, Anthony Williams How to do concurrency in C-like languages? Sequential consistency How to do concurrency in C-like languages? Sequential consistency Pthreads How to do concurrency in C-like languages? Sequential consistency Pthreads Java How to do concurrency in C-like languages? Sequential consistency Pthreads Java Expose hardware model (e.g. ClightTSO) How to do concurrency in C-like languages? Sequential consistency Pthreads Java Expose hardware model (e.g. ClightTSO) C++0x/C1x. Hans Boehm, Sarita Adve and others The design criteria Implementability Useful abstractions Precise definition Contributions A mechanised semantics of C++0x concurrency (Isabelle, HOL4) Cppmem: a tool for understanding what programs will do A proof of correctness of a compilation strategy for x86-TSO Refinements to The Standard that will improve the language How may a program execute? 1. P 7→ E1 , ..., En 2. Ei 7→ Xi1 , ..., Xim 3. is there an Xij with a race? (actually, several kinds...) Various levels of intricacy 1. Single threaded 2. Simple concurrency 3. Expert concurrency 4. Very expert concurrency Single threaded: sequenced-before and reads-from W x=2 sb int main() { int x = 2; int y = 0; y = (x==x); return 0; } rf W y=0 sb rf sb R x=2 R x=2 sb W y=1 sb Simple concurrency: Decker’s example and SC atomic_int x = 0; atomic_int y = 0; x.store(1, seq_cst); y.load(seq_cst); y.store(1, seq_cst); x.load(seq_cst); Simple concurrency: Decker’s example and SC atomic_int x = 0; atomic_int y = 0; x.store(1, seq_cst); y.load(seq_cst); y.store(1, seq_cst); x.load(seq_cst); WSC x=1 WSC y=1 RSC y=0 RSC x=0 Simple concurrency: Decker’s example and SC atomic_int x = 0; atomic_int y = 0; x.store(1, seq_cst); y.load(seq_cst); y.store(1, seq_cst); x.load(seq_cst); WSC x=1 WSC y=1 RSC y=0 RSC x=0 Simple concurrency: Decker’s example and SC atomic_int x = 0; atomic_int y = 0; x.store(1, seq_cst); y.load(seq_cst); WSC x=1 sc RSC y=0 sc y.store(1, seq_cst); x.load(seq_cst); WSC y=1 sc RSC x=1 Expert concurrency: The release-acquire idiom // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)); r = x; W x=1 sb WREL y=1 sw RACQ y=1 sb R x=1 Expert concurrency: The release-acquire idiom // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)); r = x; W x=1 sb WREL y=1 hb sw RACQ y=1 sb R x=1 Expert concurrency: The release-acquire idiom // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)); r = x; W x=1 sb WREL y=1 hb sw RACQ y=1 sb R x=1 simple-happens-before −−−−−−−−−−−−→ = sequenced-before synchronizes-with (−−−−−−−−−→ ∪ −−−−−−−−−−→)+ Expert concurrency: relaxed reads and writes are fast // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)); r = x; Expert concurrency: relaxed reads and writes are fast // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)); r = x; // sender x = ... y.store(1, release); // receiver while (0 == y.load(acquire)) { while (0 == y.load(relaxed)); } r = x; Expert concurrency: modification order atomic_int x = 0; x.store(1, relaxed); x.load(relaxed); x.store(2, relaxed); x.load(relaxed); Expert concurrency: modification order atomic_int x = 0; x.store(1, relaxed); x.load(relaxed); x.store(2, relaxed); x.load(relaxed); WRLX x=1 rf mo WRLX x=2 RRLX x=1 sb rf RRLX x=2 Very expert concurrency: consume Weaker than acquire Stronger than relaxed Non-transitive happens before! Happens before is the central relation Consistent relations Allowable read values The full model is store a = case a of Store →Tk →F r a− → b = (a, b) ∈ r is fence a = case a of Fence →Tk →F a r b = (a, b) ∈ r visible side effect set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before = {ab ∈ happens-before. let (a, b) = ab in visible side effect actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before a b} rs element rs head a = same thread a rs head ∨ is atomic rmw a is lock or unlock a = is lock a ∨ is unlock a release-sequence r a 6− → b = (a, b) ∈ / r is atomic action a = is atomic load a ∨ is atomic store a ∨ is atomic rmw a r →=r − release sequence = arel −−−−−−−−−→ b = is at atomic location b ∧ is release arel ∧ ( (b = arel ) ∨ visible sequence of side effects tail = visible sequence of side effects tail vsse head b = modification-order {c. vsse head −−−−−−−−−−→ c ∧ happens-before ¬(b −−−−−−−−→ c) ∧ modification-order modification-order s r a− →b→ − c=a− →b∧b − →c relation over s rel = domain rel ⊆ s ∧ range rel ⊆ s happens-before modification-order =⇒ ¬(b −−−−−−−−→ a))} (∀c. arel −−−−−−−−−−→ c −−−−−−−−−−→ b =⇒ rs element arel c))) is load or store a = is load a ∨ is store a s is read a = is atomic load a ∨ is atomic rmw a ∨ is load a myimage f s = {y . ∃x ∈ s. (y = f x)} release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order = release sequence actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order a b} rel −→|s = rel ∩ (s × s) is write a = is atomic store a ∨ is atomic rmw a ∨ is store a rel|s = rel ∩ (s × s) rel −→|s = rel ∩ (s × s) rel|s = rel ∩ (s × s) strict preorder ord = irreflexive ord ∧ trans ord modification-order (∀a. vsse head −−−−−−−−−−→ a −−−−−−−−−−→ c (rs element arel b ∧ arel −−−−−−−−−−→ b ∧ modification-order r hypothetical-release-sequence hypothetical release sequence = a −−−−−−−−−−−−−−−−→ b = is at atomic location b ∧ ( (b = a) ∨ is acquire a = (case memory order a of Some mem ord → (mem ord ∈ {Mo acquire, Mo acq rel, Mo seq cst} ∧ (is read a ∨ is fence a)) ∨ (* 29.8:5 states that consume fences are acquire fences. *) ((mem ord = Mo consume) ∧ is fence a) k None → is lock a) hypothetical release sequence actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order a b} is consume a = is read a ∧ (memory order a = Some Mo consume) synchronizes with = a −−−−−−−−−−→ b = (* – additional synchronization, from thread create etc. – *) modification-order (rs element a b ∧ a −−−−−−−−−−→ b ∧ modification-order visible sequences of side effects = visible sequences of side effects = λ(vsse head, b). (b, if is at atomic location b then {vsse head} ∪ visible sequence of side effects tail vsse head b else {}) modification-order (∀c. a −−−−−−−−−−→ c −−−−−−−−−−→ b =⇒ rs element a c))) visible sequences of side effects set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect = myimage (visible sequences of side effects actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect)visible-side-effect hypothetical release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order = consistent reads from mapping = consistent reads from mapping = (∀b. (is read b ∧ is at non atomic location b) =⇒ visible-side-effect (if (∃avse . avse −−−−−−−−−→ b) total over s ord = relation over s ord ∧ ord is release a = (case memory order a of Some mem ord → mem ord ∈ {Mo release, Mo acq rel, Mo seq cst} ∧ (is write a ∨ is fence a) k None → is unlock a) ord pred x ∧ x −−→ y ∧ ¬(∃z. pred z ∧ x −−→ z −−→ y ) is seq cst a = (memory order a = Some Mo seq cst) location kind = Mutex | Non atomic | Atomic ord sequenced-before type abbrev location : string ∀(y , b) ∈ − →. happens-before a −−−−−−−−→ b ∧ same location a b ∧ is at atomic location b modification-order =⇒ (x = y ) ∨ x −−−−−−−−−−→ y ) ∧ (* new CoWR *) sequenced-before happens-before a −−−−−−−−−→ x ∧ y −−−−−−−−−→ b ∧ hypothetical-release-sequence (∀(a, b) ∈ −−−−−−−−→. ∀c. rf (∃z. x −−−−−−−−−−−−−−−−→ z − → y ))) ∨ rf c− →b∧ is write a ∧ same location a b ∧ is at atomic location b (is fence a ∧ is release a ∧ is atomic action b ∧ is acquire b ∧ (∃x. same location x b ∧ is atomic action x ∧ is write x ∧ actions respect location kinds = actions respect location kinds = ∀a. case location a of Some l → (case location-kind l of Mutex → is lock or unlock a k Non atomic → is load or store a k Atomic → is load or store a ∨ is atomic action a) k None → T type abbrev thread id : string rf (* – fence synchronization – *) (is fence a ∧ is release a ∧ is fence b ∧ is acquire b ∧ (∃x. ∃y . same location x y ∧ is atomic action x ∧ is atomic action y ∧ is write x ∧ ord x −−→ y ∧ ¬(∃z. x −−→ z −−→ y ) rf (∀(x, a) ∈ − →. rf (∃c. a −−−−−−−−−→ c − → b)) ∨ x |−−→ y = type abbrev action id : string else ¬(∃a. a − → b))) ∧ (* – release/acquire synchronization – *) (is release a ∧ is acquire b ∧ ¬ same thread a b ∧ ord well founded r = wf r rf (b ′ = b) ∧ (∃c ∈ vsse. c − → b)) rf release-sequence ord ord rf else ¬(∃a. a − → b))) ∧ (∀b. (is read b ∧ is at atomic location b) =⇒ (if (∃(b ′ , vsse) ∈ visible-sequences-of-side-effects. (b ′ = b)) then (∃(b ′ , vsse) ∈ visible-sequences-of-side-effects. (same location a b ∧ a ∈ actions ∧ b ∈ actions ∧ ( (* – mutex synchronization – *) sc (is unlock a ∧ is lock b ∧ a − → b) ∨ x |−−→pred y = ord modification-order =⇒ (c = a) ∨ a −−−−−−−−−−→ c) ∧ (* new CoRW *) happens-before (∀(a, b) ∈ −−−−−−−−→. ∀c. sequenced-before a −−−−−−−−−→ x ∧ hypothetical-release-sequence rf (∃z. x −−−−−−−−−−−−−−−−→ z − → b))) ∨ rf c− →a∧ is write b ∧ same location a b ∧ is at atomic location a (is atomic action a ∧ is release a ∧ is fence b ∧ is acquire b ∧ (∃x. same location a x ∧ is atomic action x ∧ modification-order =⇒ c −−−−−−−−−−→ b) ∧ rf (∀(a, b) ∈ − →. is atomic rmw b sequenced-before type abbrev val : string is at location kind = is at location kind = case location a of Some l → (location-kind l = lk0 ) k None → F memory order enum = Mo seq cst | Mo relaxed | Mo release | Mo acquire | Mo consume | Mo acq rel is at mutex location a = is at location kind a Mutex x −−−−−−−−−→ b ∧ modification-order release-sequence =⇒ a |−−−−−−−−−−→ b) ∧ rf (∃z. a −−−−−−−−−→ z − → x))))) rf synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence = (∀(a, b) ∈ − →. is seq cst b sc →λc. =⇒ (¬ is seq cst a ∨ a |− synchronizes with actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence a b} (* -Fence restrictions- *) (action id of (Lock aid ) = aid) ∧ ) = aid) ∧ (action id of (Unlock aid (action id of (Atomic load aid ) = aid) ∧ (action id of (Atomic store aid ) = aid) ∧ ) = aid) ∧ (action id of (Atomic rmw aid (action id of (Load aid ) = aid) ∧ (action id of (Store aid ) = aid) ∧ ) = aid) (action id of (Fence aid is write c ∧same location b c b)) ∧ (* 29.3:3 *) sequenced-before carries-a-dependency-to (∀a. ∀(x, b) ∈ −−−−−−−−−→. ∀y . (is fence x ∧ is seq cst x ∧ is atomic action b ∧ is write a ∧ same location a b ∧ carries a dependency to = a −−−−−−−−−−−−−→ b = rf sequenced-before data-dependency a ((− → ∩ −−−−−−−−−→) ∪ −−−−−−−−−→)+ b is at non atomic location a = is at location kind a Non atomic action = Lock of action id thread id location | Unlock of action id thread id location | Atomic load of action id thread id memory order enum location val | Atomic store of action id thread id memory order enum location val | Atomic rmw of action id thread id memory order enum location val val | Load of action id thread id location val | Store of action id thread id location val | Fence of action id thread id memory order enum rf then (∃avse . avse −−−−−−−−−→ b ∧ avse − → b) a −−−−−−−−−−−−−−−−→ b ∨ ord (∀x ∈ s. ∀y ∈ s. x −−→ y ∨ y −−→ x ∨ (x = y )) strict total order over s ord = strict preorder ord ∧ total over s ord ord visible-side-effect synchronizes-with additional-synchronized-with sc rf a |− →x ∧y − → b) modification-order =⇒ (y = a) ∨ a −−−−−−−−−−→ y ) ∧ carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf = is at atomic location a = is at location kind a Atomic carries a dependency to actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf a b} same thread a b = (thread id of a = thread id of b) release-sequence same location a b = (location a = location b) (* 29.3:4 *) sequenced-before rf (∀(a, x) ∈ −−−−−−−−−→. ∀(y , b) ∈ − →. (is atomic action a ∧ is fence x ∧ is seq cst x ∧ is write a ∧ same location a b ∧ sc x− → b ∧ is atomic action b) dependency-ordered-before dependency ordered before = a −−−−−−−−−−−−−−−→ d = a ∈ actions ∧ d ∈ actions ∧ (∃b. is release a ∧ is consume b ∧ modification-order =⇒ (y = a) ∨ a −−−−−−−−−−→ y ) ∧ rf (∃e. a −−−−−−−−−→ e − → b) ∧ threadwise relation over s rel = relation over s rel ∧ (∀(a, b) ∈ rel. same thread a b) (* 29.3:5 *) carries-a-dependency-to (b −−−−−−−−−−−−−→ d ∨ (b = d))) sequenced-before dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to = sequenced-before (∀(a, x) ∈ −−−−−−−−−→. ∀(y , b) ∈ −−−−−−−−−→. ∀z. (is atomic action a ∧ is fence x ∧ is seq cst x ∧ is write a ∧ is fence y ∧ is seq cst y ∧ is atomic action b ∧ same location a b ∧ sc rf x− →y ∧z − → b) dependency ordered before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to a b} locations of actions = {l. ∃a. (location a = Some l)} modification-order =⇒ (z = a) ∨ a −−−−−−−−−−→ z) simple happens before simple happens before = −−−−−−−−−−−−−→ = (thread (thread (thread (thread (thread (thread (thread (thread id id id id id id id id of of of of of of of of (Lock tid ) = tid) ∧ (Unlock tid ) = tid) ∧ (Atomic load tid ) = tid) ∧ (Atomic store tid ) = tid) ∧ (Atomic rmw tid ) = tid) ∧ (Load tid ) = tid) ∧ (Store tid ) = tid) ∧ (Fence tid ) = tid) well formed action a = case a of mem ord → mem ord ∈ Atomic load {Mo relaxed, Mo acquire, Mo seq cst, Mo consume} mem ord → mem ord ∈ k Atomic store {Mo relaxed, Mo release, Mo seq cst} mem ord → mem ord ∈ k Atomic rmw {Mo relaxed, Mo release, Mo acquire, Mo acq rel, Mo seq cst, Mo consume} k →T sequenced-before all data dependency synchronizes-with (−−−−−−−−−→ ∪ −−−−−−−−−−→)+ all data dependency = −−−−−−−−−−−−→ = rf (− → ∪ −−−−−−−−−−−−−→) shb consistent control dependency = consistent control dependency = irreflexive (−−→) control-dependency dependency-ordered-before )= )= (location (Lock l) = Some l) ∧ (location (Unlock l) = Some l) ∧ l ) = Some l) ∧ (location (Atomic load l ) = Some l) ∧ (location (Atomic store (location (Atomic rmw l ) = Some l) ∧ l ) = Some l) ∧ (location (Load l ) = Some l) ∧ (location (Store (location (Fence ) = None) (value read (Atomic load v ) = Some v ) ∧ v ) = Some v ) ∧ (value read (Atomic rmw (value read (Load v ) = Some v ) ∧ (value read = None) (value written (Atomic store v ) = Some v ) ∧ v ) = Some v ) ∧ (value written (Atomic rmw (value written (Store v ) = Some v ) ∧ (value written = None) is lock a = case a of Lock is unlock a = case a of Unlock →Tk →F →Tk →F is atomic load a = case a of Atomic load is atomic store a = case a of Atomic store →Tk →F →Tk →F well formed threads = well formed threads = inj on action id of (actions) ∧ (∀a. well formed action a) ∧ threadwise relation over actions sequenced-before ∧ threadwise relation over actions data-dependency ∧ threadwise relation over actions control-dependency ∧ strict preorder sequenced-before ∧ strict preorder data-dependency ∧ strict preorder control-dependency ∧ relation over actions additional-synchronized-with ∧ (∀a. thread id of a ∈ threads) ∧ actions respect location kinds ∧ data-dependency ⊆ sequenced-before well formed reads from mapping = well formed reads from mapping = →Tk →F →Tk →F synchronizes-with sequenced-before sequenced-before r consistent inter thread happens before = consistent inter thread happens before = inter-thread-happens-before irreflexive (−−−−−−−−−−−−−−−→) happens-before happens before = −−−−−−−−→ = sequenced-before inter-thread-happens-before −−−−−−−−−→ ∪ −−−−−−−−−−−−−−−→ all sc actions = all sc actions = {a. (is seq cst a ∨ is lock a ∨ is unlock a)} consistent execution actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc = well formed threads actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency ∧ consistent locks actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency sc ∧ ( let release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let hypothetical-release-sequence = hypothetical release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let synchronizes-with = synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence in let carries-a-dependency-to = carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf in let dependency-ordered-before = dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to in let inter-thread-happens-before = inter thread happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency synchronizes-with dependency-ordered-before in let happens-before = happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency inter-thread-happens-before in let visible-side-effect = visible side effect set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before in let visible-sequences-of-side-effects = visible sequences of side effects set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect in consistent inter thread happens before inter-thread-happens-before ∧ consistent sc order actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order sc happens-before ∧ consistent modification order actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency sc modification-order happens-before ∧ well formed reads from mapping actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf ∧ consistent reads from mapping actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf sc modification-order happens-before visible-side-effect visible-sequences-of-side-effects) rf rf ′ ′ rf (∀a. ∀a . ∀b. a − →b∧a − → b =⇒ (a = a )) ∧ rf (∀(a, b) ∈ − →. same location a b ∧ (value read b = value written a) ∧ (a 6= b) ∧ (is at mutex location a =⇒ is unlock a ∧ is lock b) ∧ (is at non atomic location a =⇒ is store a ∧ is load b) ∧ (is at atomic location a =⇒ (is atomic store a ∨ is atomic rmw a ∨ is store a) ∧ (is atomic load b ∨ is atomic rmw b ∨ is load b))) all lock or unlock actions at lopt as = {a ∈ as. is lock or unlock a ∧ (location a = lopt)} consistent locks = consistent locks = ∀l ∈ locations of actions. (location-kind l = Mutex) =⇒ ( let lock unlock actions = all lock or unlock actions at (Some l)actions in sc →|lock unlock actions in let lock order = − (* 30.4.1:5 - The implementation shall serialize those (lock and unlock) operations. *) strict total order over lock unlock actions lock order ∧ (* 30.4.1:1 A thread owns a mutex from the time it successfully calls one of the lock functions until it calls unlock.*) (* 30.4.1:20 Requires: The calling thread shall own the mutex. *) (* 30.4.1:21 Effects: Releases the calling threads ownership of the mutex.*) (∀au ∈ lock unlock actions. is unlock au =⇒ (∃al ∈ lock unlock actions. (* 30.4.1:7 Effects: Blocks the calling thread until ownership of the mutex can be obtained for the calling thread.*) (* 30.4.1:8 Postcondition: The calling thread owns the mutex. *) (∀al ∈ lock unlock actions. is lock al =⇒ (∀au ∈ lock unlock actions. lock order au |−−−−−−→ al =⇒ is unlock au ))) indeterminate reads actions threads = indeterminate reads = ′ lock order is load a = case a of Load −−−−−−−−−−−−−−−→ ∪ (−−−−−−−−−−→ ◦ −−−−−−−−−→) in r (− → ∪ (−−−−−−−−−→ ◦ − →))+ →) ∧ relation over actions (− al |−−−−−−→ au ∧ same thread al au ∧ is lock al )) ∧ is atomic rmw a = case a of Atomic rmw all data dependency irreflexive ((−−−−−−−−−−−→ ∪ −−−−−−−−−−−−→)+ ) inter-thread-happens-before inter thread happens before = −−−−−−−−−−−−−−−→ = synchronizes-with )= + consistent simple happens before shb = let r = −−−−−−−−−−→ ∪ (memory order (Atomic load mem ord Some mem ord) ∧ (memory order (Atomic store mem ord Some mem ord) ∧ mem ord (memory order (Atomic rmw Some mem ord) ∧ mem ord) = (memory order (Fence Some mem ord) ∧ (memory order = None) carries-a-dependency-to rf consistent sc order = consistent sc order = {b. is read b ∧ ¬(∃a. a − → b)} happens-before let sc happens before = −−−−−−−−→|all sc actions in modification-order let sc mod order = −−−−−−−−−−→|all sc actions in sc →) ∧ strict total order over all sc actions (− sc happens before unsequenced races = unsequenced races = {(a, b). (a 6= b) ∧ same location a b ∧ (is write a ∨ is write b) ∧ same thread a b ∧ sc −−−−−−−−−−−→ ⊆ − →∧ sc mod order sc −−−−−−−−→ ⊆ − → sequenced-before modification-order (∀a. ∀b. a −−−−−−−−−−→ b =⇒ same location a b) ∧ (∀l ∈ locations of actions. case location-kind l of Atomic → ( let actions at l = {a. (location a = Some l)} in let writes at l = {a at l. (is store a ∨ is atomic store a ∨ is atomic rmw a)} in strict total order over writes at l happens-before modification-order (−−−−−−−−−−→|actions at l ) ∧ (* happens-before at the writes of l is a subset of mo for l *) happens-before sequenced-before modification-order sc (−−−−−−−−−→ ◦ (− →|is fence ) sequenced-before ◦ −−−−−−−−−→|writes modification-order modification-order (−−−−−−−−−−→|actions at l ) happens-before at l ) data races′ actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc = let release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let hypothetical-release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let synchronizes-with = synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence in let carries-a-dependency-to = carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf in let dependency-ordered-before = dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to in let inter-thread-happens-before = inter thread happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency synchronizes-with dependency-ordered-before in let happens-before = happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency inter-thread-happens-before in data races actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before = {})) visible-side-effect visible side effect = a −−−−−−−−−→ b = happens-before a −−−−−−−−→ b ∧ is write a ∧ is read b ∧ same location a b ∧ ¬(∃c. (c 6= a) ∧ (c 6= b) ∧ is write c ∧ same location c b ∧ happens-before data races = data races = {(a, b). (a 6= b) ∧ same location a b ∧ (is write a ∨ is write b) ∧ ¬ same thread a b ∧ ¬(is atomic action a ∧ is atomic action b) ∧ ¬(a −−−−−−−−→ b ∨ b −−−−−−−−→ a)} −−−−−−−−→|writes at l ⊆ −−−−−−−−−−→ ∧ (* Mo seq cst fences impose modification order *) ⊆ −−−−−−−−−−→) k →( let actions at l = {a. (location a = Some l)} in happens-before sequenced-before ¬(a −−−−−−−−−→ b ∨ b −−−−−−−−−→ a)} consistent modification order = consistent modification order = a −−−−−−−−→ c −−−−−−−−→ b) cpp memory model opsem (p ∈ ′ program) = let executions = {(actions, threads, location-kind, sequenced-before, additional-synchronized-with, data-dependency, control-dependency, rf, modification-order, sc). opsem p actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency ∧ consistent execution actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc} in if ∃(actions, threads, location-kind, sequenced-before, additional-synchronized-with, data-dependency, control-dependency, rf, modification-order, sc) ∈ executions . (indeterminate reads actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf 6= {}) ∨ (unsequenced races actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency 6= {}) ∨ (data races′ actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc 6= {}) then {} else executions The full model is store a = case a of Store →Tk →F r a− → b = (a, b) ∈ r is fence a = case a of Fence →Tk →F a r b = (a, b) ∈ r visible side effect set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before = {ab ∈ happens-before. let (a, b) = ab in visible side effect actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before a b} rs element rs head a = same thread a rs head ∨ is atomic rmw a is lock or unlock a = is lock a ∨ is unlock a release-sequence r a 6− → b = (a, b) ∈ / r is atomic action a = is atomic load a ∨ is atomic store a ∨ is atomic rmw a r →=r − release sequence = arel −−−−−−−−−→ b = is at atomic location b ∧ is release arel ∧ ( (b = arel ) ∨ visible sequence of side effects tail = visible sequence of side effects tail vsse head b = modification-order {c. vsse head −−−−−−−−−−→ c ∧ happens-before ¬(b −−−−−−−−→ c) ∧ modification-order modification-order s r a− →b→ − c=a− →b∧b − →c relation over s rel = domain rel ⊆ s ∧ range rel ⊆ s happens-before modification-order =⇒ ¬(b −−−−−−−−→ a))} (∀c. arel −−−−−−−−−−→ c −−−−−−−−−−→ b =⇒ rs element arel c))) is load or store a = is load a ∨ is store a s is read a = is atomic load a ∨ is atomic rmw a ∨ is load a myimage f s = {y . ∃x ∈ s. (y = f x)} release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order = release sequence actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order a b} rel −→|s = rel ∩ (s × s) is write a = is atomic store a ∨ is atomic rmw a ∨ is store a rel|s = rel ∩ (s × s) rel −→|s = rel ∩ (s × s) rel|s = rel ∩ (s × s) strict preorder ord = irreflexive ord ∧ trans ord modification-order (∀a. vsse head −−−−−−−−−−→ a −−−−−−−−−−→ c (rs element arel b ∧ arel −−−−−−−−−−→ b ∧ modification-order r hypothetical-release-sequence hypothetical release sequence = a −−−−−−−−−−−−−−−−→ b = is at atomic location b ∧ ( (b = a) ∨ is acquire a = (case memory order a of Some mem ord → (mem ord ∈ {Mo acquire, Mo acq rel, Mo seq cst} ∧ (is read a ∨ is fence a)) ∨ (* 29.8:5 states that consume fences are acquire fences. *) ((mem ord = Mo consume) ∧ is fence a) k None → is lock a) hypothetical release sequence actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order a b} is consume a = is read a ∧ (memory order a = Some Mo consume) synchronizes with = a −−−−−−−−−−→ b = (* – additional synchronization, from thread create etc. – *) modification-order (rs element a b ∧ a −−−−−−−−−−→ b ∧ modification-order visible sequences of side effects = visible sequences of side effects = λ(vsse head, b). (b, if is at atomic location b then {vsse head} ∪ visible sequence of side effects tail vsse head b else {}) modification-order (∀c. a −−−−−−−−−−→ c −−−−−−−−−−→ b =⇒ rs element a c))) visible sequences of side effects set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect = myimage (visible sequences of side effects actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect)visible-side-effect hypothetical release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order = consistent reads from mapping = consistent reads from mapping = (∀b. (is read b ∧ is at non atomic location b) =⇒ visible-side-effect (if (∃avse . avse −−−−−−−−−→ b) total over s ord = relation over s ord ∧ ord is release a = (case memory order a of Some mem ord → mem ord ∈ {Mo release, Mo acq rel, Mo seq cst} ∧ (is write a ∨ is fence a) k None → is unlock a) ord pred x ∧ x −−→ y ∧ ¬(∃z. pred z ∧ x −−→ z −−→ y ) is seq cst a = (memory order a = Some Mo seq cst) location kind = Mutex | Non atomic | Atomic ord sequenced-before type abbrev location : string ∀(y , b) ∈ − →. happens-before a −−−−−−−−→ b ∧ same location a b ∧ is at atomic location b modification-order =⇒ (x = y ) ∨ x −−−−−−−−−−→ y ) ∧ (* new CoWR *) sequenced-before happens-before a −−−−−−−−−→ x ∧ y −−−−−−−−−→ b ∧ hypothetical-release-sequence (∀(a, b) ∈ −−−−−−−−→. ∀c. rf (∃z. x −−−−−−−−−−−−−−−−→ z − → y ))) ∨ rf c− →b∧ is write a ∧ same location a b ∧ is at atomic location b (is fence a ∧ is release a ∧ is atomic action b ∧ is acquire b ∧ (∃x. same location x b ∧ is atomic action x ∧ is write x ∧ actions respect location kinds = actions respect location kinds = ∀a. case location a of Some l → (case location-kind l of Mutex → is lock or unlock a k Non atomic → is load or store a k Atomic → is load or store a ∨ is atomic action a) k None → T type abbrev thread id : string rf (* – fence synchronization – *) (is fence a ∧ is release a ∧ is fence b ∧ is acquire b ∧ (∃x. ∃y . same location x y ∧ is atomic action x ∧ is atomic action y ∧ is write x ∧ ord x −−→ y ∧ ¬(∃z. x −−→ z −−→ y ) rf (∀(x, a) ∈ − →. rf (∃c. a −−−−−−−−−→ c − → b)) ∨ x |−−→ y = type abbrev action id : string else ¬(∃a. a − → b))) ∧ (* – release/acquire synchronization – *) (is release a ∧ is acquire b ∧ ¬ same thread a b ∧ ord well founded r = wf r rf (b ′ = b) ∧ (∃c ∈ vsse. c − → b)) rf release-sequence ord ord rf else ¬(∃a. a − → b))) ∧ (∀b. (is read b ∧ is at atomic location b) =⇒ (if (∃(b ′ , vsse) ∈ visible-sequences-of-side-effects. (b ′ = b)) then (∃(b ′ , vsse) ∈ visible-sequences-of-side-effects. (same location a b ∧ a ∈ actions ∧ b ∈ actions ∧ ( (* – mutex synchronization – *) sc (is unlock a ∧ is lock b ∧ a − → b) ∨ x |−−→pred y = ord modification-order =⇒ (c = a) ∨ a −−−−−−−−−−→ c) ∧ (* new CoRW *) happens-before (∀(a, b) ∈ −−−−−−−−→. ∀c. sequenced-before a −−−−−−−−−→ x ∧ hypothetical-release-sequence rf (∃z. x −−−−−−−−−−−−−−−−→ z − → b))) ∨ rf c− →a∧ is write b ∧ same location a b ∧ is at atomic location a (is atomic action a ∧ is release a ∧ is fence b ∧ is acquire b ∧ (∃x. same location a x ∧ is atomic action x ∧ modification-order =⇒ c −−−−−−−−−−→ b) ∧ rf (∀(a, b) ∈ − →. is atomic rmw b sequenced-before type abbrev val : string is at location kind = is at location kind = case location a of Some l → (location-kind l = lk0 ) k None → F memory order enum = Mo seq cst | Mo relaxed | Mo release | Mo acquire | Mo consume | Mo acq rel is at mutex location a = is at location kind a Mutex x −−−−−−−−−→ b ∧ modification-order release-sequence =⇒ a |−−−−−−−−−−→ b) ∧ rf (∃z. a −−−−−−−−−→ z − → x))))) rf synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence = (∀(a, b) ∈ − →. is seq cst b sc →λc. =⇒ (¬ is seq cst a ∨ a |− synchronizes with actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence a b} (* -Fence restrictions- *) (action id of (Lock aid ) = aid) ∧ ) = aid) ∧ (action id of (Unlock aid (action id of (Atomic load aid ) = aid) ∧ (action id of (Atomic store aid ) = aid) ∧ ) = aid) ∧ (action id of (Atomic rmw aid (action id of (Load aid ) = aid) ∧ (action id of (Store aid ) = aid) ∧ ) = aid) (action id of (Fence aid is write c ∧same location b c b)) ∧ (* 29.3:3 *) sequenced-before carries-a-dependency-to (∀a. ∀(x, b) ∈ −−−−−−−−−→. ∀y . (is fence x ∧ is seq cst x ∧ is atomic action b ∧ is write a ∧ same location a b ∧ carries a dependency to = a −−−−−−−−−−−−−→ b = rf sequenced-before data-dependency a ((− → ∩ −−−−−−−−−→) ∪ −−−−−−−−−→)+ b is at non atomic location a = is at location kind a Non atomic action = Lock of action id thread id location | Unlock of action id thread id location | Atomic load of action id thread id memory order enum location val | Atomic store of action id thread id memory order enum location val | Atomic rmw of action id thread id memory order enum location val val | Load of action id thread id location val | Store of action id thread id location val | Fence of action id thread id memory order enum rf then (∃avse . avse −−−−−−−−−→ b ∧ avse − → b) a −−−−−−−−−−−−−−−−→ b ∨ ord (∀x ∈ s. ∀y ∈ s. x −−→ y ∨ y −−→ x ∨ (x = y )) strict total order over s ord = strict preorder ord ∧ total over s ord ord visible-side-effect synchronizes-with additional-synchronized-with sc rf a |− →x ∧y − → b) modification-order =⇒ (y = a) ∨ a −−−−−−−−−−→ y ) ∧ carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf = is at atomic location a = is at location kind a Atomic carries a dependency to actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf a b} same thread a b = (thread id of a = thread id of b) release-sequence same location a b = (location a = location b) (* 29.3:4 *) sequenced-before rf (∀(a, x) ∈ −−−−−−−−−→. ∀(y , b) ∈ − →. (is atomic action a ∧ is fence x ∧ is seq cst x ∧ is write a ∧ same location a b ∧ sc x− → b ∧ is atomic action b) dependency-ordered-before dependency ordered before = a −−−−−−−−−−−−−−−→ d = a ∈ actions ∧ d ∈ actions ∧ (∃b. is release a ∧ is consume b ∧ modification-order =⇒ (y = a) ∨ a −−−−−−−−−−→ y ) ∧ rf (∃e. a −−−−−−−−−→ e − → b) ∧ threadwise relation over s rel = relation over s rel ∧ (∀(a, b) ∈ rel. same thread a b) (* 29.3:5 *) carries-a-dependency-to (b −−−−−−−−−−−−−→ d ∨ (b = d))) sequenced-before dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to = sequenced-before (∀(a, x) ∈ −−−−−−−−−→. ∀(y , b) ∈ −−−−−−−−−→. ∀z. (is atomic action a ∧ is fence x ∧ is seq cst x ∧ is write a ∧ is fence y ∧ is seq cst y ∧ is atomic action b ∧ same location a b ∧ sc rf x− →y ∧z − → b) dependency ordered before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to a b} locations of actions = {l. ∃a. (location a = Some l)} modification-order =⇒ (z = a) ∨ a −−−−−−−−−−→ z) simple happens before simple happens before = −−−−−−−−−−−−−→ = (thread (thread (thread (thread (thread (thread (thread (thread id id id id id id id id of of of of of of of of (Lock tid ) = tid) ∧ (Unlock tid ) = tid) ∧ (Atomic load tid ) = tid) ∧ (Atomic store tid ) = tid) ∧ (Atomic rmw tid ) = tid) ∧ (Load tid ) = tid) ∧ (Store tid ) = tid) ∧ (Fence tid ) = tid) well formed action a = case a of mem ord → mem ord ∈ Atomic load {Mo relaxed, Mo acquire, Mo seq cst, Mo consume} mem ord → mem ord ∈ k Atomic store {Mo relaxed, Mo release, Mo seq cst} mem ord → mem ord ∈ k Atomic rmw {Mo relaxed, Mo release, Mo acquire, Mo acq rel, Mo seq cst, Mo consume} k →T sequenced-before all data dependency synchronizes-with (−−−−−−−−−→ ∪ −−−−−−−−−−→)+ all data dependency = −−−−−−−−−−−−→ = rf (− → ∪ −−−−−−−−−−−−−→) shb consistent control dependency = consistent control dependency = irreflexive (−−→) control-dependency dependency-ordered-before )= )= (location (Lock l) = Some l) ∧ (location (Unlock l) = Some l) ∧ l ) = Some l) ∧ (location (Atomic load l ) = Some l) ∧ (location (Atomic store (location (Atomic rmw l ) = Some l) ∧ l ) = Some l) ∧ (location (Load l ) = Some l) ∧ (location (Store (location (Fence ) = None) (value read (Atomic load v ) = Some v ) ∧ v ) = Some v ) ∧ (value read (Atomic rmw (value read (Load v ) = Some v ) ∧ (value read = None) (value written (Atomic store v ) = Some v ) ∧ v ) = Some v ) ∧ (value written (Atomic rmw (value written (Store v ) = Some v ) ∧ (value written = None) is lock a = case a of Lock is unlock a = case a of Unlock →Tk →F →Tk →F is atomic load a = case a of Atomic load is atomic store a = case a of Atomic store →Tk →F →Tk →F well formed threads = well formed threads = inj on action id of (actions) ∧ (∀a. well formed action a) ∧ threadwise relation over actions sequenced-before ∧ threadwise relation over actions data-dependency ∧ threadwise relation over actions control-dependency ∧ strict preorder sequenced-before ∧ strict preorder data-dependency ∧ strict preorder control-dependency ∧ relation over actions additional-synchronized-with ∧ (∀a. thread id of a ∈ threads) ∧ actions respect location kinds ∧ data-dependency ⊆ sequenced-before well formed reads from mapping = well formed reads from mapping = →Tk →F →Tk →F synchronizes-with sequenced-before sequenced-before r consistent inter thread happens before = consistent inter thread happens before = inter-thread-happens-before irreflexive (−−−−−−−−−−−−−−−→) happens-before happens before = −−−−−−−−→ = sequenced-before inter-thread-happens-before −−−−−−−−−→ ∪ −−−−−−−−−−−−−−−→ all sc actions = all sc actions = {a. (is seq cst a ∨ is lock a ∨ is unlock a)} consistent execution actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc = well formed threads actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency ∧ consistent locks actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency sc ∧ ( let release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let hypothetical-release-sequence = hypothetical release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let synchronizes-with = synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence in let carries-a-dependency-to = carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf in let dependency-ordered-before = dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to in let inter-thread-happens-before = inter thread happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency synchronizes-with dependency-ordered-before in let happens-before = happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency inter-thread-happens-before in let visible-side-effect = visible side effect set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before in let visible-sequences-of-side-effects = visible sequences of side effects set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order happens-before visible-side-effect in consistent inter thread happens before inter-thread-happens-before ∧ consistent sc order actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order sc happens-before ∧ consistent modification order actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency sc modification-order happens-before ∧ well formed reads from mapping actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf ∧ consistent reads from mapping actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf sc modification-order happens-before visible-side-effect visible-sequences-of-side-effects) rf rf ′ ′ rf (∀a. ∀a . ∀b. a − →b∧a − → b =⇒ (a = a )) ∧ rf (∀(a, b) ∈ − →. same location a b ∧ (value read b = value written a) ∧ (a 6= b) ∧ (is at mutex location a =⇒ is unlock a ∧ is lock b) ∧ (is at non atomic location a =⇒ is store a ∧ is load b) ∧ (is at atomic location a =⇒ (is atomic store a ∨ is atomic rmw a ∨ is store a) ∧ (is atomic load b ∨ is atomic rmw b ∨ is load b))) all lock or unlock actions at lopt as = {a ∈ as. is lock or unlock a ∧ (location a = lopt)} consistent locks = consistent locks = ∀l ∈ locations of actions. (location-kind l = Mutex) =⇒ ( let lock unlock actions = all lock or unlock actions at (Some l)actions in sc →|lock unlock actions in let lock order = − (* 30.4.1:5 - The implementation shall serialize those (lock and unlock) operations. *) strict total order over lock unlock actions lock order ∧ (* 30.4.1:1 A thread owns a mutex from the time it successfully calls one of the lock functions until it calls unlock.*) (* 30.4.1:20 Requires: The calling thread shall own the mutex. *) (* 30.4.1:21 Effects: Releases the calling threads ownership of the mutex.*) (∀au ∈ lock unlock actions. is unlock au =⇒ (∃al ∈ lock unlock actions. (* 30.4.1:7 Effects: Blocks the calling thread until ownership of the mutex can be obtained for the calling thread.*) (* 30.4.1:8 Postcondition: The calling thread owns the mutex. *) (∀al ∈ lock unlock actions. is lock al =⇒ (∀au ∈ lock unlock actions. lock order au |−−−−−−→ al =⇒ is unlock au ))) indeterminate reads actions threads = indeterminate reads = ′ lock order is load a = case a of Load −−−−−−−−−−−−−−−→ ∪ (−−−−−−−−−−→ ◦ −−−−−−−−−→) in r (− → ∪ (−−−−−−−−−→ ◦ − →))+ →) ∧ relation over actions (− al |−−−−−−→ au ∧ same thread al au ∧ is lock al )) ∧ is atomic rmw a = case a of Atomic rmw all data dependency irreflexive ((−−−−−−−−−−−→ ∪ −−−−−−−−−−−−→)+ ) inter-thread-happens-before inter thread happens before = −−−−−−−−−−−−−−−→ = synchronizes-with )= + consistent simple happens before shb = let r = −−−−−−−−−−→ ∪ (memory order (Atomic load mem ord Some mem ord) ∧ (memory order (Atomic store mem ord Some mem ord) ∧ mem ord (memory order (Atomic rmw Some mem ord) ∧ mem ord) = (memory order (Fence Some mem ord) ∧ (memory order = None) carries-a-dependency-to rf consistent sc order = consistent sc order = {b. is read b ∧ ¬(∃a. a − → b)} happens-before let sc happens before = −−−−−−−−→|all sc actions in modification-order let sc mod order = −−−−−−−−−−→|all sc actions in sc →) ∧ strict total order over all sc actions (− sc happens before unsequenced races = unsequenced races = {(a, b). (a 6= b) ∧ same location a b ∧ (is write a ∨ is write b) ∧ same thread a b ∧ sc −−−−−−−−−−−→ ⊆ − →∧ sc mod order sc −−−−−−−−→ ⊆ − → sequenced-before modification-order (∀a. ∀b. a −−−−−−−−−−→ b =⇒ same location a b) ∧ (∀l ∈ locations of actions. case location-kind l of Atomic → ( let actions at l = {a. (location a = Some l)} in let writes at l = {a at l. (is store a ∨ is atomic store a ∨ is atomic rmw a)} in strict total order over writes at l happens-before modification-order (−−−−−−−−−−→|actions at l ) ∧ (* happens-before at the writes of l is a subset of mo for l *) happens-before sequenced-before modification-order sc (−−−−−−−−−→ ◦ (− →|is fence ) sequenced-before ◦ −−−−−−−−−→|writes modification-order modification-order (−−−−−−−−−−→|actions at l ) happens-before at l ) data races′ actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc = let release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let hypothetical-release-sequence = release sequence set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency modification-order in let synchronizes-with = synchronizes with set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc release-sequence hypothetical-release-sequence in let carries-a-dependency-to = carries a dependency to set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf in let dependency-ordered-before = dependency ordered before set actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order release-sequence carries-a-dependency-to in let inter-thread-happens-before = inter thread happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency synchronizes-with dependency-ordered-before in let happens-before = happens before actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency inter-thread-happens-before in data races actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency happens-before = {})) visible-side-effect visible side effect = a −−−−−−−−−→ b = happens-before a −−−−−−−−→ b ∧ is write a ∧ is read b ∧ same location a b ∧ ¬(∃c. (c 6= a) ∧ (c 6= b) ∧ is write c ∧ same location c b ∧ happens-before data races = data races = {(a, b). (a 6= b) ∧ same location a b ∧ (is write a ∨ is write b) ∧ ¬ same thread a b ∧ ¬(is atomic action a ∧ is atomic action b) ∧ ¬(a −−−−−−−−→ b ∨ b −−−−−−−−→ a)} −−−−−−−−→|writes at l ⊆ −−−−−−−−−−→ ∧ (* Mo seq cst fences impose modification order *) ⊆ −−−−−−−−−−→) k →( let actions at l = {a. (location a = Some l)} in happens-before sequenced-before ¬(a −−−−−−−−−→ b ∨ b −−−−−−−−−→ a)} consistent modification order = consistent modification order = a −−−−−−−−→ c −−−−−−−−→ b) cpp memory model opsem (p ∈ ′ program) = let executions = {(actions, threads, location-kind, sequenced-before, additional-synchronized-with, data-dependency, control-dependency, rf, modification-order, sc). opsem p actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency ∧ consistent execution actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc} in if ∃(actions, threads, location-kind, sequenced-before, additional-synchronized-with, data-dependency, control-dependency, rf, modification-order, sc) ∈ executions . (indeterminate reads actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf 6= {}) ∨ (unsequenced races actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency 6= {}) ∨ (data races′ actions threads location-kind sequenced-before additional-synchronized-with data-dependency control-dependency rf modification-order sc 6= {}) then {} else executions Cppmem helps explore and understand the model Cppmem Code in, all executions out Confidence and speed Communication How may a program execute in Cppmem? 1. P 7→ E1 , ..., En — tracking constraints 2. Ei 7→ Xi1 , ..., Xim — automatically uses formal model 3. is there an Xij with a race? Verifying a compilation strategy The prototype x86 implementation Operation load(non-seq cst) load(seq cst) store(non-seq cst) store(seq cst) fence(non-seq cst) x86 Implementation mov lock xadd(0) mov lock xchg no-op x86-TSO is stronger and simpler Theorem Eopsem evt comp Ex86 consistent execution Xwitness evt comp −1 valid execution Xx86 Refinements to the standard The standardisation process 1300 page definition 3231 working documents Rapperswil The current state of the standard Fixed: Happens-before Coherence seq_cst atomics The current state of the standard Fixed: Happens-before Coherence seq_cst atomics were not SC! (Thanks anonymous reviewer) The current state of the standard Fixed: Happens-before Coherence seq_cst atomics were not SC! Not fixed: Self satisfying conditionals (Thanks anonymous reviewer) Coherence All forbidden! W x=1 mo W x=2 rf rf R x=1 hb R x=2 W x=2 CoWW W x=1 hb R x=2 CoWR CoRR W x=1 hb mo W x=2 mo rf W x=1 rf mo CoRW R x=1 hb W x=2 Self-satisfying conditionals r1 = x.load(mo_relaxed); if (r1 == 42) y.store(r1, mo_relaxed); RRLX x=42 sb WRLX y=42 rf rf r2 = y.load(mo_relaxed); if (r2 == 42) x.store(42, mo_relaxed); RRLX y=42 sb WRLX x=42 Conclusion It’s OK to like the C++0x memory model design Our formal model lets us make fun things (go use it!) Optimized compilation? Static analysis? Dynamic analysis? Observational congruence? Program logics?