My gut feeling is this is a stupid question, as no one has ever asked it. But I am still a bit obsessed with it.
I understand that a std::memory_order_release operation guarantees that all writes prior to it can be seen by another thread when that thread has loaded the atomic variable with std::memory_order_acquire.
My question is: what's the exact definition of "prior to"? Say, in this situation
void write_other()
{
other_var1 = true;
other_var2 = true;
}
void write() // writer thread
{
write_other();
x.store(true, std::memory_order_relaxed);
y.store(true, std::memory_order_release); // release!!
}
void read() // reader thread
{
while (!y.load(std::memory_order_acquire)) {} // acquire!!
assert(x.load(std::memory_order_relaxed)); // this is definitely true
assert(other_var1.load(std::memory_order_relaxed)); // is this true?
assert(other_var2.load(std::memory_order_relaxed)); // is this true?
}
Then in the main thread, I launch the two threads.
std::vector<std::thread> threads;
threads.push_back(std::thread(&read));
threads.push_back(std::thread(&write));
In the writer thread, the write to other_var1 and other_var2 happen in function "write_other" that is called by the thread entry function "write". In this situation, can the updates to other_var1 and other_var2 be synchronized to the loading of y in the reader thread?
In other words, what's the scope of the relative order guarantee? Should it cover only the current code block? Or should it cover all updates that have ever happened in the writer thread before the std::memory_order_release operation?