Memory ordering and RMW operations

59 views Asked by At

Suppose I make two relaxed modifications to two atomic objects in thread0, one per each object, and then make thread1 observe the modification that came second in thread0. Now without memory fences, if thread1 were to try and load the first object, it might not get the newly stored value (without release on the store and an acquire on the observation), but what if it does an atomic read-modify-write operation on it?

#include <stdatomic.h>
#include <stddef.h>
#include <assert.h>
int _Atomic atoInt = 0;
_Atomic _Bool atoBool= 0;

void thread0(void){
    atomic_store_explicit(&atoInt,42,memory_order_relaxed);

    atomic_signal_fence(memory_order_seq_cst); //prevent compiler reordering

    atomic_store_explicit(&atoBool,1,memory_order_relaxed);
}

void thread1(void){
    //observe the 0 => 1 transition
    while(0==(atomic_load_explicit(&atoBool,memory_order_relaxed))){}

    atomic_signal_fence(memory_order_seq_cst); //prevent compiler reordering

    //could still get the stale value because release/acquire wan't used
    assert(
        0==atomic_load_explicit(&atoInt,memory_order_relaxed)
        || 42==atomic_load_explicit(&atoInt,memory_order_relaxed)
    );

    //should hold regardless because it's an RMW?
    assert(42==atomic_fetch_sub_explicit(&atoInt,1,memory_order_relaxed));
}

Based on my understanding of how cache coherence and fences work, I believe the RMW operation must necessarily get the new value.

Is this correct?

0

There are 0 answers