An atomic variable is shared among several concurrently running threads. To my knowledge a thread can read a stale value of it performing a relaxed load:
x.load(std::memory_order_relaxed)
What if we use release-acquire synchronization? As far as I can get from the docs, the thread which performs acquire is guaranteed to see what the releasing thread has written into the variable.
// Thread 1:
x.store(33, std::memory_order_release);
// Thread 2:
x.load(std::memory_order_acquire)
Will thread 2 always see the fresh value in this case?
Now if we add the third thread, which performs relaxed store, to the previous example, thread 2 may not see its updates as the synchronization is established between thread 1 and 2. Am I correct?
Finally, read-modify-write operations are said to always operate on fresh values. Bearing this point in mind, does it mean that if we load after read-modify-write operation, we will see the value at least as fresh as that operation did?
// Thread 1:
x.fetch_add(1, std::memory_order_relaxed); // read-modify-write operation
if (x.load(std::memory_order_relaxed) == 3)
fire();
// Thread 2:
x.fetch_add(2, std::memory_order_relaxed); // will see thread 1 modification
if (x.load(std::memory_order_relaxed) == 3) // will see (at least) what was fetched + 2
fire();
For x
initially zero can I be sure that fire
will be called at least once in this case? All my tests proved that it works, but perhaps it's just a matter of my compiler or hardware.
I'm also curious about the ordering. There is a clear dependency between x
modification and load, therefore I suppose these instructions not to be reordered in spite of the fact that relaxed order is specified. Or am I wrong?
Aucun commentaire:
Enregistrer un commentaire