Reputation: 9540
Consider the following code:
#include <stdatomic.h>
#include <stdlib.h>
void write(int *j, _Atomic int *i){
*j = rand();
atomic_store_explicit(i, 1, memory_order_release);
}
void read(int *j, _Atomic int *i){
if(atomic_load_explicit(i, memory_order_acquire)){
int var = *j;
atomic_store_explicit(i, 0, memory_order_release);
}
}
Assuming that int *j
and _Atomic int *i
are unrelated memory locations refering to the same objects in both of the functions and 2 separate threads run each functions in an infinite loop is the following true:
If atomic_load_explicit(i, memory_order_acquire)
reads a value written by atomic_store_explicit(i, 1, memory_order_release)
then int var = *j;
reads a value written by *j = rand();
exactly in the same iteration?
My understanding:
*j = rand();
is Sequenced before atomic_store_explicit(i, 1, memory_order_release);
since these are 2 statements in program order.
If atomic_load_explicit(i, memory_order_acquire)
reads a value written by atomic_store_explicit(i, 1, memory_order_release);
then atomic_load_explicit(i, memory_order_acquire)
synchronizes with atomic_store_explicit(i, 1, memory_order_release);
Similarly atomic_load_explicit(i, memory_order_acquire)
is Sequenced before int var = *j;
.
Therefore *j = rand();
inter-thread happens before int var = *j;
.
Accroding to 5.1.2.4/p20
*j = rand();
is a visible side effect with respect to int var = *j;
QUESTION: Is it really possible to provide visibility guarantees even on non-atomic object if there are acquire
-release
operations in between with synchronize-with relations?
The main question is if *j = rand();
might be reordered with atomic_store_explicit(i, 1, memory_order_release);
or similarly atomic_load_explicit(i, memory_order_acquire
might be reordered with int var = *j;
On x86
reads and writes are not reordered with like operations so assembly code compiled for x86
cannot provide a counter-example.
Upvotes: 2
Views: 112