I am trying to learn about execution order involving atomic variables in C , and I have the following code.
According to cppreference, I have the following reasoning:
C enforce 1->2 order when executing Because no load/store can be moved before an acquire-load within the same thread.
C enforce 3->4 order when executing The same reason as 1
C enforce 2->3 order when executing
Because 2 is a release-store to y, and 3 is an acquire-load from y. So 2 should be visible to 3. Thus, 2 should be executed before 3, and 3 will read the result of 2's write.
C enforce 4->1 order when executing The same reason as 3
From reasoning 1/2/3, we can deduce a execution order of 1 -> 2 -> 3 -> 4, and it will break reasoning 4.
From reasoning 1/2/4, we can deduce a execution order of 3 -> 4 -> 1 -> 2, and it will break reasoning 3.
Seems there are conflicts here.
int main() {
while(true) {
std::atomic<int> x, y;
x.store(10);
y.store(20);
auto f1 = [&]() {
int r1 = x.load(std::memory_order_acquire); // 1
y.store(r1, std::memory_order_release); // 2
};
auto f2 = [&]() {
int r2 = y.load(std::memory_order_acquire); // 3
x.store(r2, std::memory_order_release); // 4
};
std::thread t1(f1);
std::thread t2(f2);
t1.join();
t2.join();
printf("%d %d\n", x.load(), y.load());
}
}
-- EDIT --
My reasoning about why 2 must happens before 3:
- From preshing, y.store(rel) syncs-with y.load(acq).
- Then according to cppreference, we can have y.store(rel) Inter-thread happens-before y.load(acq).
- Then y.store(rel) happens-before y.load(acq).
- So y.store(rel) must happens before y.load(acq)
CodePudding user response:
1 will "happen before" 2, and 3 will "happen before" 4. This part is correct.
However, for 3 to "synchronize with" (and "happen after") 2, it must successfully read the value written by 2.
If it doesn't read that value (because it ended up running before 2), then no synchronization happens, and no ordering is imposed on 4 relative to 1. In this case, 3 is said to be "coherence-ordered before" 2.
The same applies to 1 reading the value from 4.
