Suppose I have 2 threads:
int value = 0;
std::atomic<bool> ready = false;
thread 1:
value = 1
ready = true;
thread 2:
while (!ready);
std::cout << value;
Is this program able to output 0?
I read about the C++ memory model - specifically, sequential consistency, which I believe is the default, and it wasn't particularly clear. Is the compiler only required to put atomic operations in the correct order relative to each other, or is it required to put atomic operations in the right order relative to all other operations?
By default operations on atomic variables are done using the memory_order_seq_cst
semantics, which guarantees that no reordering will be done.
Thus the line: value = 1
cannot be reordered below the atomic assignment: value = 1
, so the line std::cout << value;
will always print 1.
By the same rules, the line: std::cout << value;
cannot be reordered
above the line: while (!ready);
.
Is this program able to output 0?
No.
Your reasoning is correct. In ISO C++ seq_cst and acq_rel atomics can create happens-before / after relationships between threads, making it safe for one thread to write a non-atomic variable and then another thread to read it without data-race UB.
And you've correctly done so in this case: the spin-wait loop is a seq-cst load from the flag that only exits the loop upon seeing a true
value. The evaluation of non-atomic value
happens-after the load that sees the true
. And in the writer, the sequential-release store makes sure that the flag store is not seen before the value store.
When compiling to asm for a normal ISA, compilers have to respect ordering of non-atomic stores before release-stores, and of non-atomic loads after acquire loads. Unless it can somehow prove that there would still be UB for any other possible thread observing this.
It acts like a memory barrier, as per ShadowRanger's response. However, for more details on why it does that, I suggest looking at Herb Sutter's talk on atomic weapons. He goes into great detail about how and why atomics work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With