summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew W. Nosenko <andrew.w.nosenko@gmail.com>2012-04-26 17:02:56 +0300
committerMartin Sustrik <sustrik@250bpm.com>2012-04-29 07:30:37 +0200
commitcdbaa67ff5fdb7cebab670e6f7906d9e81ae7f0a (patch)
treee7b925bf24ecf966577c06333cb22f7e1b208f6d
parent98d4e212bc6379888c006aadb89eb1b96e0b3ddb (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.
-rw-r--r--src/atomic_counter.hpp5
-rw-r--r--src/atomic_ptr.hpp11
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