Hi, On 2025-03-08 14:12:13 +0200, Alexander Korotkov wrote: > I'm not an expert in formal specifications of memory models. But I'm quite > surprised we're discussing whether memory barrier on compare-exchange > failure might matter. For me at least the fact > that __atomic_compare_exchange_n() have failure_memorder argument is a > quite an evidence of that.
I wasn't trying to say that the failure memory order doesn't matter, just that an *acquire* barrier might be strong enough in the failure case if you look at it from the POV of C++/C11's memory model. The docs for __atomic_compare_exchange_n say: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html#index-_005f_005fatomic_005fcompare_005fexchange_005fn > Otherwise, false is returned and memory is affected according to > failure_memorder. This memory order cannot be __ATOMIC_RELEASE nor > __ATOMIC_ACQ_REL. It also cannot be a stronger order than that specified by > success_memorder. Note that the generated code you showed *did* unconditionally execute the load with acquire semantics. Which means that that one can argue that this is *NOT* a compiler bug. >From the C/C++ standard atomics model it doesn't make sense to say that a failed CAS has release semantics, as there simply isn't a write that could be ordered! What their barriers guarantee is ordering between multiple memory operation, you can't order multiple writes if you don't have multiple writes... The synchronization in the C/C++ model is only established between accesses of the same variable and there's no write in the case of a failed CAS, so there's nothing that could establish a release-acquire ordering. Unfortunately that model doesn't mesh well with barriers that aren't attached to read/modify operations. Which is what we ended up with... Greetings, Andres Freund