Following code writes into atomic A, B variable and reads them in opposite order in another thread:
#include <atomic>
#include <thread>
// Initially.
std::atomic<int> A = std::atomic<int>(0);
std::atomic<int> B = std::atomic<int>(0);
// Thread 1
void write()
{
A.store(1, std::memory_order_release); // line 1
B.store(1, std::memory_order_release); // line 2
}
// Thread 2
void read()
{
int valB = B.load(std::memory_order_acquire); // line 3
int valA = A.load(std::memory_order_acquire); // line 4
}
int main()
{
std::thread t1(write), t2(read);
t1.join();
t2.join();
return 0;
}
Ideally, given the release-acquire ordering on atomic B, the load on line 3, should synchronize for completion of store on line 1, since it happens to be before release operation on line 2. But the reference only mentions (emphasis, mine) -
All memory writes (non-atomic and relaxed atomic) that happened-before the atomic store from the point of view of thread A, become visible side-effects in thread B.
So, a release-acquire ordering on B, doesn't take into effect the atomic oparations on other variables that aren't relaxed memory ordering?
Is it possible to have then, values for valB = 1, valA = 0, after read() concludes in Thread 2, since B's memory ordering doesn't care about other atomic operations that aren't relaxed? Do we need sequential consistency here?
write()on the main thread isn't really shorter and definitely changes the nature of the question (unintentionally).std::thread's constructor, which state that completion ofthread's constructor synchronizes-with the beginning of invocation of the supplied callable on the new thread. So in the code shown here, it is flat out impossible for the thread runningreadto see anything other than1and1, but not for the reasons you're asking about.