3 ms·
Being atomic is not enough. It's too easy to use two atomics operations and assume they'll be sequentially consistent. For example, suppose we have: A = 0
by Strilanc 13y ago
Being atomic is not enough. It's too easy to use two atomics operations and assume they'll be sequentially consistent.
For example, suppose we have:
A = 0
B = 0
Producer:
while true:
AtomicIncrement A
AtomicIncrement B
Consumer:
while true:
postA = AtomicDecrement A
postB = AtomicDecrement B
assert postA == postB // wrong
The assertion is wrong, when you're dealing with relaxed atomics. For example, the producer can be optimized into this either by the compiler or by caching layers:
int savedUpA = 0
while true:
savedUpA++
if (savedUpA == 100)
AtomicAdd A, 100
AtomicIncrement B
In which case the consumer will often see that postA != postB.
Thankfully, languages are apparently converging on "every atomic write is a release barrier" and "every atomic read is an acquire barrier", which makes these sorts of optimizations illegal (releasing B's new value requires releasing A's new value).