Slides

advertisement
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?
Download