-
Notifications
You must be signed in to change notification settings - Fork 807
Description
[atomics.order] p5 says:
It also ensures that a memory_order::seq_cst load A of M gets its value either from the last modification of M that precedes A in S or from some non-memory_order::seq_cst modification of M that does not happen before any modification of M that precedes A in S.
The note is inaccurate because the emphasized part doesn't cover this case:
std::atomic<int> m = 0;
// thread 1:
m.store(1,std::memory_order::relaxed); // #1
// thread 2:
if(m.fetch_add(1,std::memory_order::seq_cst)==1){ // #2
m.load(std::memory_order::seq_cst); // #3
}#1 indeed does not happen before #2(however, #1 precedes #2 in the modification order of m), and #2 precedes #3 in S, however, #3 is impossible to read #1.
So, saying "does not happen before" is insufficient and doesn't accurately express the intent of the formal wording(especially, [atomics.order] p3 and p4).
Assuming X is any modification of M that precedes A in S, if A were to read any non-memory_order::seq_cst modification that precedes X in the modification order of M, [atomics.order] p3.3 would render that A is coherence-ordered before X, that is, A would precede X in S, which conflicts with the assumption that X precedes A in S. This means, if A doesn't read the last X, it must read some non-memory_order::seq_cst modification that follows X in the modification order of M.
Suggested Resolution:
or from some non-memory_order::seq_cst modification of M that does not precede any modification in the modification order of
Mthat precedes A in S.