diff options
author | Rickard Green <[email protected]> | 2015-01-05 11:04:34 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2015-01-14 20:24:45 +0100 |
commit | 24fa075b5c0d54f2035a2ff510a82aa19187eda4 (patch) | |
tree | 2e26371bbcf360ae53f75c6bad1799aa375c1b72 /erts/include/internal/ethread_inline.h | |
parent | ce73c38b10d1dee5209b505ef054b108e747b522 (diff) | |
download | otp-24fa075b5c0d54f2035a2ff510a82aa19187eda4.tar.gz otp-24fa075b5c0d54f2035a2ff510a82aa19187eda4.tar.bz2 otp-24fa075b5c0d54f2035a2ff510a82aa19187eda4.zip |
Improve ethread atomics based on GCC builtins
* Use of __atomic builtins when available.
* Improved configure test that checks for missing memory
barrier in __sync_synchronize(). The old approach was to
verify known working gcc versions and check gcc version at
compile time. Besides not being very safe, the old approach
often unnecessarily caused usage of the very expensive
workaround.
* Introduced (no overhead) workaround for missing clobber in
__sync_synchronize() when using buggy LLVM implementation of
__sync_synchronize().
* Implement native memory barriers for ARM processors supporting
the DMB instruction.
* Use of volatile store on Alpha as atomic set operation if no
__atomic_store_n() is available (already used on x86/x86_64
Sparc V9, PowerPC, and MIPS). Fallback used when not using
volatile store is typically very expensive.
* Use volatile load on Alpha and ARM as atomic read operation
if no __atomic_load_n() is available (already used on
x86/x86_64 Sparc V9, PowerPC, and MIPS). Fallback when not
using volatile load is typically very expensive.
Diffstat (limited to 'erts/include/internal/ethread_inline.h')
-rw-r--r-- | erts/include/internal/ethread_inline.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/erts/include/internal/ethread_inline.h b/erts/include/internal/ethread_inline.h index ffb756c84f..c09a67619a 100644 --- a/erts/include/internal/ethread_inline.h +++ b/erts/include/internal/ethread_inline.h @@ -20,6 +20,29 @@ #ifndef ETHREAD_INLINE_H__ #define ETHREAD_INLINE_H__ +#define ETHR_GCC_COMPILER_FALSE 0 /* Not a gcc compatible compiler */ +#define ETHR_GCC_COMPILER_TRUE 1 /* The GNU gcc compiler */ +/* Negative integers for gcc compatible compilers */ +#define ETHR_GCC_COMPILER_CLANG -1 /* The Clang gcc compatible compiler */ +#define ETHR_GCC_COMPILER_ICC -2 /* The Intel gcc compatible compiler */ +/* Line them up... */ + +/* + * Unfortunately there is no easy and certain way of + * detecting a true gcc compiler, since the compatible + * ones all define the same defines as the true gnu-gcc... + */ +#if !defined(__GNUC__) && !defined(__GNUG__) +# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_FALSE +#elif defined(__clang__) +# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_CLANG +#elif defined(__ICC) || defined(__INTEL_COMPILER) +# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_ICC +#else +/* Seems to be the true gnu-gcc... */ +# define ETHR_GCC_COMPILER ETHR_GCC_COMPILER_TRUE +#endif + #if !defined(__GNUC__) # define ETHR_AT_LEAST_GCC_VSN__(MAJ, MIN, PL) 0 #elif !defined(__GNUC_MINOR__) |