Commit cfe8acb1 authored by Davi Arnaut's avatar Davi Arnaut

Bug#56760: my_atomics failures on osx10.5-x86-64bit

The problem was due to a misuse of GCC asm constraints used to
implement a atomic load. On x86_64, the load was implemented
as a cmpxchg which implicitly uses the eax register as a
source and destination operand, yet the dummy value used for
comparison wasn't being properly loaded into eax (and other
problems).

The core problem is that cmpxchg is unnecessary as a load
on x86_64 as there are other simpler instructions such
as xadd. Even though, such instructions are only used to
have a memory barrier as load and stores are atomic by
definition. Hence, the solution is to explicitly issue the
required CPU and compiler barriers.

include/atomic/x86-gcc.h:
  Issue a synchronizing instruction before loading the value.
  Afterwards, issue a compiler barrier to prevent reordering.
parent e1e81ceb
...@@ -78,15 +78,15 @@ ...@@ -78,15 +78,15 @@
: "memory") : "memory")
/* /*
Actually 32-bit reads/writes are always atomic on x86 Actually 32/64-bit reads/writes are always atomic on x86_64,
But we add LOCK_prefix here anyway to force memory barriers nonetheless issue memory barriers as appropriate.
*/ */
#define make_atomic_load_body(S) \ #define make_atomic_load_body(S) \
ret=0; \ /* Serialize prior load and store operations. */ \
asm volatile (LOCK_prefix "; cmpxchg %2, %0" \ asm volatile ("mfence" ::: "memory"); \
: "=m" (*a), "=a" (ret) \ ret= *a; \
: "r" (ret), "m" (*a) \ /* Prevent compiler from reordering instructions. */ \
: "memory") asm volatile ("" ::: "memory")
#define make_atomic_store_body(S) \ #define make_atomic_store_body(S) \
asm volatile ("; xchg %0, %1;" \ asm volatile ("; xchg %0, %1;" \
: "=m" (*a), "+r" (v) \ : "=m" (*a), "+r" (v) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment