diff options
author | Andrew W. Nosenko <andrew.w.nosenko@gmail.com> | 2012-04-26 17:02:56 +0300 |
---|---|---|
committer | Martin Sustrik <sustrik@250bpm.com> | 2012-04-29 07:30:37 +0200 |
commit | cdbaa67ff5fdb7cebab670e6f7906d9e81ae7f0a (patch) | |
tree | e7b925bf24ecf966577c06333cb22f7e1b208f6d /src | |
parent | 98d4e212bc6379888c006aadb89eb1b96e0b3ddb (diff) |
atomic: prefer GCC __sync_*() builtins over inline asm
Use GCC __sync_*() builtins when compiler claims to be GCC (GCC itself,
Clang...)
It can be disabled explicitly by using XS_DISABLE_GCC_SYNC_BUILTINS
define. Just for any case.
* src/atomic_counter.hpp [__GNUC__ && !XS_DISABLE_GCC_SYNC_BUILTINS]:
(atomic_counter_t::add):
(atomic_counter_t::sub):
* src/atomic_ptr.hpp [__GNUC__ && !XS_DISABLE_GCC_SYNC_BUILTINS]:
(atomic_ptr_t::xchg):
(atomic_ptr_t::cas):
Prefer GCC __sync_*() builtins over inline asm.
Diffstat (limited to 'src')
-rw-r--r-- | src/atomic_counter.hpp | 5 | ||||
-rw-r--r-- | src/atomic_ptr.hpp | 11 |
2 files changed, 16 insertions, 0 deletions
diff --git a/src/atomic_counter.hpp b/src/atomic_counter.hpp index 07002af..bd89f72 100644 --- a/src/atomic_counter.hpp +++ b/src/atomic_counter.hpp @@ -81,6 +81,8 @@ namespace xs #if defined XS_ATOMIC_COUNTER_WINDOWS old_value = InterlockedExchangeAdd ((LONG*) &value, increment_); +#elif defined __GNUC__ && !defined XS_DISABLE_GCC_SYNC_BUILTINS + old_value = __sync_fetch_and_add (&value, increment_); #elif defined XS_ATOMIC_COUNTER_ATOMIC_H integer_t new_value = atomic_add_32_nv (&value, increment_); old_value = new_value - increment_; @@ -121,6 +123,9 @@ namespace xs LONG delta = - ((LONG) decrement); integer_t old = InterlockedExchangeAdd ((LONG*) &value, delta); return old - decrement != 0; +#elif defined __GNUC__ && !defined XS_DISABLE_GCC_SYNC_BUILTINS + integer_t new_value = __sync_sub_and_fetch (&value, decrement); + return (new_value != 0); #elif defined XS_ATOMIC_COUNTER_ATOMIC_H int32_t delta = - ((int32_t) decrement); integer_t nv = atomic_add_32_nv (&value, delta); diff --git a/src/atomic_ptr.hpp b/src/atomic_ptr.hpp index 8d4c770..2e585b7 100644 --- a/src/atomic_ptr.hpp +++ b/src/atomic_ptr.hpp @@ -82,6 +82,15 @@ namespace xs { #if defined XS_ATOMIC_PTR_WINDOWS return (T*) InterlockedExchangePointer ((PVOID*) &ptr, val_); +#elif defined __GNUC__ && !defined XS_DISABLE_GCC_SYNC_BUILTINS + { + T* ov; + do + { + ov = const_cast<T*>(ptr); + } while (!__sync_bool_compare_and_swap (&ptr, ov, val_)); + return ov; + } #elif defined XS_ATOMIC_PTR_ATOMIC_H return (T*) atomic_swap_ptr (&ptr, val_); #elif defined XS_ATOMIC_PTR_X86 @@ -125,6 +134,8 @@ namespace xs #if defined XS_ATOMIC_PTR_WINDOWS return (T*) InterlockedCompareExchangePointer ( (volatile PVOID*) &ptr, val_, cmp_); +#elif defined __GNUC__ && !defined XS_DISABLE_GCC_SYNC_BUILTINS + return (T*) __sync_val_compare_and_swap (&ptr, cmp_, val_); #elif defined XS_ATOMIC_PTR_ATOMIC_H return (T*) atomic_cas_ptr (&ptr, cmp_, val_); #elif defined XS_ATOMIC_PTR_X86 |