I'm thinking of whether or not it is possible for atomic variable to load the old value in acquire-release pair. Let's suppose we have atomic variable x, and we store that variable with release semantics and later load it with acquire semantics is it possible in theory to read the old value?
std::atomic<int> x = 0;
void thread_1()
{
x.store(1, std::memory_order_release);
}
void thread_2()
{
assert(x.load(std::memory_order_acquire) != 0);
}
if function thread 1 is finished when thread 2 loads the x (so the new value is stored) is it possible for thread 2 to load old value from x? In other words if actual store to x is done before the load is it possible for assert to fire?
As far as I understood from articles in internet it is possible, but I cannot understand why. Memory fence generated by store to x guaranties to empty store buffer, while acquire memory fence in load from x is guaranteed to invalidate cache line, so it has to read up-to-date value.
added
Does it mean that acquire-release by itself doesn't have any enforced ordering? It's only anything that was done before release will happen before release and everything that is done after acquire will happen after it, so acquire-release pair enforces ordering on the other operations (why??). Did I get it right? Does it mean that in the code bellow assert is guaranteed to do not fire
std::atomic<int> x = 0;
std::atomic<int> y = 0;
void thread_1()
{
y.store(1, std::memory_order_relaxed);
x.store(1, std::memory_order_release);
}
void thread_2()
{
x.load(std::memory_order_acquire);
assert(y.load(std::memory_order_relaxed) != 0);
}
of course again if the thread 1 was already finished the store. If we replace x.load with while (x.load() == 0) this will 100% work, but I don't know what causes this to work.
And what if I replace the code with code bellow
std::atomic<int> x = 0;
void thread_1()
{
x.exchange(1, std::memory_order_acq_rel);
}
void thread_2()
{
assert(x.exchange(0, std::memory_order_acq_rel) != 0);
}
Does it change anything?
Thanks.
std::atomic<int> x = 0;
it doesn't matter what memory order you use! – Hesitation