I am reading the book "C++ Concurrency in Action" section 5.3 on Memory Model of C++ and listing 5.5 below confuses me:
std::atomic<bool> x,y;
std::atomic<int> z;
void write_x_then_y()
{
// Is there a Happens-Before relationship for statement (1) and (2) below?
x.store(true,std::memory_order_relaxed); // --> (1)
y.store(true,std::memory_order_relaxed); // --> (2)
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed));
if(x.load(std::memory_order_relaxed))
++z;
}
int main()
{
x=false;
y=false;
z=0;
std::thread a(write_x_then_y); std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load()!=0);
}
What confuses me is function void write_x_then_y(). The author says "This time the assert at the end of main() can fire" and statement (1) on atomic variable x has a "happens-before" relationship with statement (2) on atomic variable y. But I thought with std::memory_order_relaxed, there is no synchronization between different atomic variables, and compiler/CPU can reorder these two statements without violating the program semantics.
The happensbefore relationships from listing 5.5 are shown in figure 5.4, along with a possible outcome.
