According to cppreference, we can use release-acquire semantics to ensure write-read precedence between two threads as follows:
// Thread A
1. Write to X
2. Atomic store to Y with std::memory_order_release
// Thread B
3. Atomic load at Y with std::memory_order_acquire
4. Read at X
Supposing that 2
is ordered before 3
(take it as a given that this occurs according to Y), we are guaranteed that A
's write to X
is visible to B
since we can establish a total order on the events (as conveniently described by my enumeration above) because 1 sequenced-before 2 synchronizes-with 3 sequenced-before 4
and because release-acquire ensure that all of A
's writes are visible to B
after 3
.
However, the link above explicitly states that in this situation "all memory writes (non-atomic and relaxed atomic) [by A become] visible side-effects in thread B." My question is then: are "visible side-effects" considered writes made B
to threads previously unaware of A
's writes?
In other words, suppose I had a third thread C
and another atomic:
// Thread A
1. Write to X
2. Atomic store to Y with std::memory_order_release
// Thread B
3. Atomic load at Y with std::memory_order_acquire
4. Read at X
5. Atomic store to Z with std::memory_order_release
// Thread C
6. Atomic load at Z with std::memory_order_acquire
7. Read at X
(Assume similarly that 5 happens-before 6
). Would C
read A
's write to X
? Or is B
's "visible side-effect" on X
not considered a write?
Best Answer
Formally, you are asking if the side effect on X in thread A is visible with respect to value computation of X in thread C.
For that to be true, 1 needs to happen-before 7.
A happens-before B is defined, as synchronizes-with or inter-thread happens-before, and the latter is defined as
So yes, it is perfectly transitive across multiple threads. In particular, in your case,
1 sequenced-before 2
2 synchronizes-with 3
3 sequenced-before 5
5 synchronizes-with 6
6 sequenced-before 7
Therefore, 1 happens-before 7, therefore 1 is a visible side-effect with respect to 7, and therefore the value of non-atomic scalar object X as determined by the value computation of X (your "Read at X") is guaranteed to be the value stored by the visible side-effect 1.