Is there any case where we'd want to load an atomic with memory_order_acquire without a corresponding store to the same atomic with memory_order_release?
For example, if I have this piece of code:
std::atomic<uint64_t> state;
std::atomic<uint64_t> count;
// Thread 1
while (true)
{
auto expected = state.load(memory_order_relaxed);
auto desired = get_desired(expected);
if (state.compare_exchange_weak(expected, desired, memory_order_relaxed, memory_order_relaxed) { <----- (A)
count.fetch_add(1, memory_order_relaxed); <---- (B)
break;
}
}
// Thread 2
auto state = state.load(memory_order_acquire); <----- (C)
auto count = count.load(memory_order_relaxed); <----- (D)
The memory_order_acquire in Thread 2 should prevent the load of count from being moved before the load of state, but since we use memory_order_relaxed everywhere else, am I correct in saying that Thread 2 may see an updated value of count that's possibly newer than state i.e. see the effects of (B) before it sees the effects of the compare_exchange from (A)?
If I wanted the effect of (A) to always be visible to Thread 2 when it loads it in (C), then would I change (B) to memory_order_release, use memory_order_acquire in (D) and flip the order of (C) and (D)?