https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005

--- Comment #10 from James Y Knight <foom at fuhm dot net> ---
I suppose since it doesn't affect most common platforms, nobody's noticed the
brokenness yet?

ARM is probably the most common architecture which is missing atomics on common
CPU models, but when targeting common OSes (Linux, FreeBSD), you get to use the
kernel atomic cmpxchg helpers, so the issue doesn't arise there.

I haven't tested, but I don't think MIPS16 would be broken, since MIPS has
native atomics, just not in the MIPS16 ISA. So, it calls out-of-line libgcc
__sync_* routines, implemented in MIPS32 and which use LL/SC instructions.
There's no problem mixing those with native load/store instructions.


Anyways, for why mixing native load/store with __atomic_* functions is wrong,
consider,
int value = 4;

Thread1:
int oldval = __atomic_fetch_add(&value, 1, __ATOMIC_SEQ_CST);

Thread2:
__atomic_store_n(&value, 0, __ATOMIC_SEQ_CST);

The only allowable results after executing both threads should be:
oldval = 0, value = 1 -- if atomic_store executes first.
oldval = 4, value = 0 -- if atomic_fetch_add executes first.

But, if you implement __atomic_fetch_add with a lock, and implement
__atomic_store with a native store instruction, you may get the "impossible"
result,
oldval = 4, value = 5 -- if atomic_store executes *during* atomic_fetch_add,
between the load and store instructions. Oops.

Reply via email to