diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2016-11-23 13:55:00 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2016-11-24 14:19:04 +0300 |
commit | f82a19e191b4515f04b3e57b9bab3e73e4c02ca7 (patch) | |
tree | 9f4b80f5cf0810ffae8509d932c3bebf564e2e89 | |
parent | 8e4213ff4329d5bcbbb76644084ccf3c76c3ef25 (diff) | |
download | libatomic_ops-f82a19e191b4515f04b3e57b9bab3e73e4c02ca7.tar.gz |
Code refactoring of Clang double-wide intrinsic workarounds (gcc/x86)
(fix commits 9803386, f6a1b68, eb6d4fd)
* src/atomic_ops/sysdeps/gcc/generic.h [AO_HAVE_DOUBLE_PTR_STORAGE
&& !AO_HAVE_double_store] (AO_double_store): Do not define if
AO_SKIPATOMIC_double_store.
* src/atomic_ops/sysdeps/gcc/generic.h [AO_HAVE_DOUBLE_PTR_STORAGE
&& !AO_HAVE_double_store_release] (AO_double_store_release): Do not
define if AO_SKIPATOMIC_double_load.
* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET
&& __clang__ && !__x86_64__ && !__APPLE_CC__ && !__CYGWIN__
&& !AO_PREFER_BUILTIN_ATOMICS] (AO_SKIPATOMIC_double_load,
AO_SKIPATOMIC_double_load_acquire, AO_SKIPATOMIC_double_store,
AO_SKIPATOMIC_double_store_release): Define internal macro (undefined
at the end of file).
* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET
&& (__clang__ && !__x86_64__ && !__APPLE_CC__ && !__CYGWIN__
&& !AO_PREFER_BUILTIN_ATOMICS) || (__APPLE_CC__ && __x86_64__))]
(AO_SKIPATOMIC_double_compare_and_swap_ANY): Move definition here
(remove at other places in this file); undefine at the end of the file.
* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET]: Check
AO_SKIPATOMIC_double_compare_and_swap_ANY instead of checking multiple
macros to detect whether a workaround for the CAS (and others)
double-wide operations is needed.
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/generic.h | 5 | ||||
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/x86.h | 52 |
2 files changed, 29 insertions, 28 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/generic.h b/src/atomic_ops/sysdeps/gcc/generic.h index 69116f4..ba82e0d 100644 --- a/src/atomic_ops/sysdeps/gcc/generic.h +++ b/src/atomic_ops/sysdeps/gcc/generic.h @@ -142,7 +142,7 @@ # define AO_HAVE_double_load_acquire # endif -# ifndef AO_HAVE_double_store +# if !defined(AO_HAVE_double_store) && !defined(AO_SKIPATOMIC_double_store) AO_INLINE void AO_double_store(volatile AO_double_t *addr, AO_double_t value) { @@ -151,7 +151,8 @@ # define AO_HAVE_double_store # endif -# ifndef AO_HAVE_double_store_release +# if !defined(AO_HAVE_double_store_release) \ + && !defined(AO_SKIPATOMIC_double_store_release) AO_INLINE void AO_double_store_release(volatile AO_double_t *addr, AO_double_t value) { diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h index 041b75a..166e353 100644 --- a/src/atomic_ops/sysdeps/gcc/x86.h +++ b/src/atomic_ops/sysdeps/gcc/x86.h @@ -23,6 +23,24 @@ && !defined(AO_DISABLE_GCC_ATOMICS) # define AO_GCC_ATOMIC_TEST_AND_SET +/* TODO: Refine for newer clang releases. */ +# if defined(__clang__) \ + && !(defined(__x86_64__) || defined(__APPLE_CC__) \ + || defined(__CYGWIN__) || defined(AO_PREFER_BUILTIN_ATOMICS)) + /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all */ + /* the double-wide operations. For now, we fall back to the */ + /* non-intrinsic implementation by default. */ +# define AO_SKIPATOMIC_double_compare_and_swap_ANY +# define AO_SKIPATOMIC_double_load +# define AO_SKIPATOMIC_double_load_acquire +# define AO_SKIPATOMIC_double_store +# define AO_SKIPATOMIC_double_store_release +# elif defined(__APPLE_CC__) && defined(__x86_64__) + /* As of Apple clang-600 (based on LLVM 3.5svn), it has some bug in */ + /* double-wide CAS implementation for x64 target. */ +# define AO_SKIPATOMIC_double_compare_and_swap_ANY +# endif + #else /* AO_DISABLE_GCC_ATOMICS */ /* The following really assume we have a 486 or better. Unfortunately */ @@ -291,18 +309,8 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, #endif /* AO_DISABLE_GCC_ATOMICS */ -#if (defined(AO_PREFER_BUILTIN_ATOMICS) || !defined(__clang__) \ - || defined(__x86_64__) || defined(__APPLE_CC__) || defined(__CYGWIN__)) \ - && defined(AO_GCC_ATOMIC_TEST_AND_SET) \ - && !(defined(__APPLE_CC__) && defined(__x86_64__) && !defined(__ILP32__) \ - && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)) - - /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all the */ - /* double-wide operations. For now, we fall back to the */ - /* non-intrinsic implementation if clang/x86. */ - /* As of Apple clang-600 (based on LLVM 3.5svn), it has some bug in */ - /* double-wide CAS implementation for x64 target. */ - /* TODO: Refine for newer clang releases. */ +#if defined(AO_GCC_ATOMIC_TEST_AND_SET) \ + && !defined(AO_SKIPATOMIC_double_compare_and_swap_ANY) # if defined(__ILP32__) || !defined(__x86_64__) /* 32-bit AO_t */ \ || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) /* 64-bit AO_t */ @@ -319,18 +327,6 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, # define AO_ACCESS_double_CHECK_ALIGNED # include "../loadstore/double_atomic_load_store.h" -# ifdef AO_GCC_ATOMIC_TEST_AND_SET - /* Double-wide loads and stores are ordered. */ -# define AO_double_load_acquire(addr) AO_double_load_read(addr) -# define AO_HAVE_double_load_acquire - -# define AO_double_store_release(addr, val) \ - (AO_nop_write(), AO_double_store(addr, val)) -# define AO_HAVE_double_store_release - -# define AO_SKIPATOMIC_double_compare_and_swap_ANY -# endif /* AO_GCC_ATOMIC_TEST_AND_SET */ - /* Returns nonzero if the comparison succeeded. */ /* Really requires at least a Pentium. */ AO_INLINE int @@ -440,8 +436,6 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, /* doesn't work. And the emulation is unsafe by our usual rules. */ /* However both are clearly useful in certain cases. */ -# define AO_SKIPATOMIC_double_compare_and_swap_ANY - AO_INLINE int AO_compare_double_and_swap_double_full(volatile AO_double_t *addr, AO_t old_val1, AO_t old_val2, @@ -483,3 +477,9 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, #ifdef AO_GCC_ATOMIC_TEST_AND_SET # include "generic.h" #endif + +#undef AO_SKIPATOMIC_double_compare_and_swap_ANY +#undef AO_SKIPATOMIC_double_load +#undef AO_SKIPATOMIC_double_load_acquire +#undef AO_SKIPATOMIC_double_store +#undef AO_SKIPATOMIC_double_store_release |