diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2016-04-01 20:34:30 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2016-04-01 20:34:30 +0300 |
commit | 03a0465f80632c408204eaa9272e6ec42d3d474f (patch) | |
tree | b0652544803cc8a9283f5adaf7b58103b572a943 | |
parent | 01d2509c13f3aa7e03cb4cbf50fda08f98725ce4 (diff) | |
download | libatomic_ops-03a0465f80632c408204eaa9272e6ec42d3d474f.tar.gz |
New macro AO_PREFER_BUILTIN_ATOMICS to rely on C11 atomics fully (AArch64)
If AO_PREFER_BUILTIN_ATOMICS is defined then inline assembly
implementation is not used.
* src/atomic_ops/sysdeps/gcc/aarch64.h (AO_SKIPATOMIC_double_load,
AO_SKIPATOMIC_double_load_acquire): Define if AO_PREFER_BUILTIN_ATOMICS.
* src/atomic_ops/sysdeps/gcc/aarch64.h (AO_nop_write, AO_double_load,
AO_double_load_acquire, AO_double_store, AO_double_store_release,
AO_double_compare_and_swap, AO_double_compare_and_swap_acquire,
AO_double_compare_and_swap_release, AO_double_compare_and_swap_full):
Do not define if AO_PREFER_BUILTIN_ATOMICS.
* src/atomic_ops/sysdeps/gcc/aarch64.h (AO_nop_write): Add comment;
remove TODO.
* src/atomic_ops/sysdeps/gcc/generic.h: Remove TODO about including
this header for other targets.
* src/atomic_ops/sysdeps/gcc/generic.h (AO_double_load): Do not define
if AO_SKIPATOMIC_double_load.
* src/atomic_ops/sysdeps/gcc/generic.h (AO_double_load_acquire): Do not
define if AO_SKIPATOMIC_double_load_acquire.
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/aarch64.h | 35 | ||||
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/generic.h | 7 |
2 files changed, 25 insertions, 17 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/aarch64.h b/src/atomic_ops/sysdeps/gcc/aarch64.h index b7f2ef0..612bc18 100644 --- a/src/atomic_ops/sysdeps/gcc/aarch64.h +++ b/src/atomic_ops/sysdeps/gcc/aarch64.h @@ -19,18 +19,23 @@ #include "../standard_ao_double_t.h" -#ifndef AO_UNIPROCESSOR - AO_INLINE void - AO_nop_write(void) - { - /* TODO: Use C++11 primitive. */ - __asm__ __volatile__("dmb ishst" : : : "memory"); - } -# define AO_HAVE_nop_write -#endif - -/* TODO: Adjust version check on fixing double-wide AO support in GCC. */ -#if __GNUC__ >= 4 +#ifdef AO_PREFER_BUILTIN_ATOMICS + /* As of clang 3.6 (and gcc 5.0), load atomics for double word are */ + /* translated to incorrect code lacking STXP (see the note below). */ +# define AO_SKIPATOMIC_double_load +# define AO_SKIPATOMIC_double_load_acquire +#else + + /* As of clang 3.6 (and gcc 4.9), __atomic_thread_fence is always */ + /* translated to DMB (which is inefficient for AO_nop_write). */ +# ifndef AO_UNIPROCESSOR + AO_INLINE void + AO_nop_write(void) + { + __asm__ __volatile__("dmb ishst" : : : "memory"); + } +# define AO_HAVE_nop_write +# endif AO_INLINE AO_double_t AO_double_load(const volatile AO_double_t *addr) @@ -68,6 +73,9 @@ } # define AO_HAVE_double_load_acquire + /* As of gcc 5.0, all built-in store and CAS atomics for double */ + /* word require -latomic, so use asm-based implementation by default. */ + AO_INLINE void AO_double_store(volatile AO_double_t *addr, AO_double_t value) { @@ -195,6 +203,7 @@ return !result; } # define AO_HAVE_double_compare_and_swap_full -#endif /* __GNUC__ >= 4 */ + +#endif /* !AO_PREFER_BUILTIN_ATOMICS */ #include "generic.h" diff --git a/src/atomic_ops/sysdeps/gcc/generic.h b/src/atomic_ops/sysdeps/gcc/generic.h index de79edb..1df2914 100644 --- a/src/atomic_ops/sysdeps/gcc/generic.h +++ b/src/atomic_ops/sysdeps/gcc/generic.h @@ -19,8 +19,6 @@ /* For the details, see GNU Manual, chapter 6.52 (Built-in functions */ /* for memory model aware atomic operations). */ -/* TODO: Include this file for other targets if gcc 4.7+ */ - #ifdef AO_UNIPROCESSOR /* If only a single processor (core) is used, AO_UNIPROCESSOR could */ /* be defined by the client to avoid unnecessary memory barrier. */ @@ -93,7 +91,7 @@ #ifdef AO_HAVE_DOUBLE_PTR_STORAGE -# ifndef AO_HAVE_double_load +# if !defined(AO_HAVE_double_load) && !defined(AO_SKIPATOMIC_double_load) AO_INLINE AO_double_t AO_double_load(const volatile AO_double_t *addr) { @@ -105,7 +103,8 @@ # define AO_HAVE_double_load # endif -# ifndef AO_HAVE_double_load_acquire +# if !defined(AO_HAVE_double_load_acquire) \ + && !defined(AO_SKIPATOMIC_double_load_acquire) AO_INLINE AO_double_t AO_double_load_acquire(const volatile AO_double_t *addr) { |