This is from my notes on the topic of atomic modification order and sequentially consistent operation order. Please suggest corrections if you find something off the mark.
In the paper P0668R5: Revising the C++ memory model and in this question, a specific execution of the presented code snippet is discussed. This execution was not legal pre-C++20 but is allowed since C++20. In this execution the way we can derive the modification order of y
, as I see it, is as follows.
Quoting the following for reference.
If an operation A that modifies an atomic object M happens before an operation B that modifies M, then A is earlier than B in the modification order of M.
If a side effect X on an atomic object M happens before a value computation B of M, then the evaluation B takes its value from X or from a side effect Y that follows X in the modification order of M.
(x)
writes a value that is read by (1)
and so (x)
synchronizes with (1)
. (1)
is also an RMW operation. So according to intro.races/15, (x)
is before (1)
in the modification order of y
.(1)
happens before y.load(relaxed);
yet it doesn't read the value written by (1)
. It instead reads a value written by (2)
. So according to intro.races/18 (1)
is before (2)
in the modification order of y
.From the above ordering requirements, the modification order of y
in this execution turns out to be (x)
-> (1)
-> (2)
corresponding to the value sequence of 0, 1, 2, 3
.
Further, to derive the sequentially consistent operations order, in addition to the above observations, we can observe the following.
Quoting the following for reference.
There is a single total order S on all memory_order::seq_cst operations ... if A and B are memory_order::seq_cst operations and A strongly happens before B, then A precedes B in S.
An atomic operation A on some atomic object M is coherence-ordered before another atomic operation B on M if ... A and B are not the same atomic read-modify-write operation, and there exists an atomic modification X of M such that A reads the value stored by X and X precedes B in the modification order of M.
for every pair of atomic operations A and B on an object M, where A is coherence-ordered before B, ... if A and B are both memory_order::seq_cst operations, then A precedes B in S.
(2)
strongly happens before (3)
. So according to atomics.order/4, (2)
is before (3)
in the seq_cst modification order.(3)
is coherence ordered before (4)
. So, according to atomics.order/4.1, (3)
is before (4)
in the seq_cst modification order.Combining all above ordering requirements, the sequentially consistent operations order turns out to be (1)
-> (2)
-> (3)
-> (4)
.