Is there any wording in the standard that guarantees that relaxed stores to atomics won\'t be lifted above the locking of a mutex? If not, is there any wording that explicitly s
No memory operation inside a mutex protected region can 'escape' from that area. That applies to all memory operations, atomic and non-atomic.
In section 1.10.1:
a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex Correspondingly, a call that releases the same mutex will perform a release operation on those same locations
Furthermore, in section 1.10.1.6:
All operations on a given mutex occur in a single total order. Each mutex acquisition “reads the value written” by the last mutex release.
And in 30.4.3.1
A mutex object facilitates protection against data races and allows safe synchronization of data between execution agents
This means, acquiring (locking) a mutex sets a one-way barrier that prevents operations that are sequenced after the acquire (inside the protected area) from moving up across the mutex lock.
Releasing (unlocking) a mutex sets a one-way barrier that prevents operations that are sequenced before the release (inside the protected area) from moving down across the mutex unlock.
In addition, memory operations that are released by a mutex are synchronized (visible) with another thread that acquires the same mutex.
In your example, foo_has_been_set
is checked in CheckFoo
.. If it reads true
you know that the value 1 has been assigned to foo
by SetFoo
, but it is not synchronized yet.
The mutex lock that follows will acquire foo
, synchronization is complete and the assert cannot fire.