3
votes

Executing the following is an atomic RMW operation

auto value = atomic.fetch_or(value, order);

When order is std::memory_order_acq_rel we know that the load of the previous value in the atomic will acquire any release operations that might have happened previously on the same atomic. And the write will release the current thread's writes for threads that acquire the same atomic variable. Same with std::memory_order_seq_cst.

But what is the expected behavior of the write part of the RMW operation with respect to memory ordering when you use std::memory_order_acquire? Similarly, what is the expected behavior of using std::memory_order_release for the load side of the RMW operation?

1
It has the semantics as specified by order, unsurprisingly, if that's what you're asking.Passer By
@PasserBy What does a memory_order_release specify for a read operation? What happens to the read end of a RMW operation when a memory_order_release is used?Curious
Nothing, but fetch_or counts as a write as well.Passer By
@PasserBy sure, but if I use the previous value in the atomic for some logic. Can I assume that the current thread has synchronized with any other release operations? Or is the read relaxed?Curious
The fetch_or is one operation, not a separate read and write. If there happens to be an acquire somewhere down the line, then a fetch_or with release semantics will synchronize with that later read.Passer By

1 Answers

4
votes

Using std::memory_order_acquire on an atomic RMW is an acquire-only operation.
Since it does not 'release' anything, it cannot be part of a synchronizes-with relationship with another atomic acquire operation (on the same atomic variable) that occurs later.
Therefore, the equivalent for the store part is std::memory_order_relaxed

Similar reasoning for using std::memory_order_release on an RMW. It does not acquire anything, so the ordering equivalent for the load part is 'relaxed'