ARTICLE AD BOX
[atomics.order] p4 says
There is a single total order S on all memory_order::seq_cst operations, including fences, that satisfies the following constraints. First, if A and B are memory_order::seq_cst operations and A strongly happens before B, then A precedes B in S.
For example:
#include <atomic> int main(){ std::atomic<int> v; v.store(1); // A std::atomic_thread_fence(std::memory_order::seq_cst); // B }Is the fence at B so-called the memory_order::seq_cst operation? Such that we can deduce that A < B in single total order S?
The answer to the above question is the premise to reason the following example, a StoreLoad reordering litmus test where the second thread replaces the SC load with an SC fence and a relaxed load:
#include <atomic> #include <cassert> #include <thread> int main() { std::atomic<int> v = 0; std::atomic<int> v2 = 0; int c1 = 0, c2 = 0; auto t1 = std::thread([&]() { v.store(1); // #1 c1 = v2.load(); // #2 }); auto t2 = std::thread([&]() { v2.store(1); // #3 std::atomic_thread_fence(std::memory_order::seq_cst); // #4 c2 = v.load(std::memory_order::relaxed); // #5 }); t1.join(); t2.join(); if (c1 == 0) { assert(c2 == 1); } }I want to prove the assertion never fail. My reasoning is the following:
#2 reads 0 implies #2 is coherence-ordered before #3, according to the second constraint and bullet 1
Second, for every pair of atomic operations A and B on an object M, where A is coherence-ordered before B, the following four conditions are required to be satisfied by S:
if A and B are both memory_order::seq_cst operations, then A precedes B in S; andTherefore, #2 < #3. Then, assuming #5 reads 0, this implies #5 is coherence-ordered before #1, and #4 happens-before #5, according to bullet 3
if a memory_order::seq_cst fence X happens before A and B is a memory_order::seq_cst operation, then X precedes B in S; and
Therefore, #4 < #1. The cirtical point is that whether the first constraint applies to the fence. If yes, we can infer that #3 < #4 in S, then we can derive the contradiction #4 < #1 < #2 < #3 < #4, which is an invalid total order. This renders the assumed execution is impossible. In other words, the assertion never fail.
So, does the first constraint apply to fence?
