diff options
author | Adam Mitz <mitza@objectcomputing.com> | 2021-09-06 11:23:10 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-06 11:23:10 -0500 |
commit | 106e47365336828900e66d8e33934e0959ef7838 (patch) | |
tree | 67f6b1d2d3297ed866c4581747e1d67e3b409bf4 | |
parent | d035863b2a8cbf4ddade856ac723bbacecddaeb8 (diff) | |
parent | 615284ae6d9ca661bd1f644b042003dd8e161f30 (diff) | |
download | ATCD-106e47365336828900e66d8e33934e0959ef7838.tar.gz |
Merge pull request #1664 from simpsont-oci/atomic_op_gcc_tsan_fixes_and_updated_atomics
[ACE6] Update ACE_Atomic_Op_GCC to support newer __atomic operations when available
-rw-r--r-- | ACE/ace/Atomic_Op_GCC_T.inl | 112 |
1 files changed, 95 insertions, 17 deletions
diff --git a/ACE/ace/Atomic_Op_GCC_T.inl b/ACE/ace/Atomic_Op_GCC_T.inl index 90f7c4839c2..adc637e7a71 100644 --- a/ACE/ace/Atomic_Op_GCC_T.inl +++ b/ACE/ace/Atomic_Op_GCC_T.inl @@ -1,6 +1,11 @@ // -*- C++ -*- #if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1) +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) \ + || (defined (__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3))) +# define USE_GCC_CPP11_ATOMICS +#endif + ACE_BEGIN_VERSIONED_NAMESPACE_DECL template <typename T> @@ -29,91 +34,149 @@ template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator++ (void) { - return __sync_add_and_fetch (&this->value_, 1); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_add_fetch (&value_, 1, __ATOMIC_ACQ_REL); +#else + return __sync_add_and_fetch (&value_, 1); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator++ (int) { - return __sync_fetch_and_add (&this->value_, 1); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_fetch_add (&value_, 1, __ATOMIC_ACQ_REL); +#else + return __sync_fetch_and_add (&value_, 1); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator-- (void) { - return __sync_sub_and_fetch (&this->value_, 1); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_sub_fetch (&value_, 1, __ATOMIC_ACQ_REL); +#else + return __sync_sub_and_fetch (&value_, 1); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator-- (int) { - return __sync_fetch_and_sub (&this->value_, 1); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_fetch_sub (&value_, 1, __ATOMIC_ACQ_REL); +#else + return __sync_fetch_and_sub (&value_, 1); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator+= (T rhs) { - return __sync_add_and_fetch (&this->value_, rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_add_fetch (&value_, rhs, __ATOMIC_ACQ_REL); +#else + return __sync_add_and_fetch (&value_, rhs); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::operator-= (T rhs) { - return __sync_sub_and_fetch (&this->value_, rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_sub_fetch (&value_, rhs, __ATOMIC_ACQ_REL); +#else + return __sync_sub_and_fetch (&value_, rhs); +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator== (T rhs) const { - return (this->value_ == rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) == rhs; +#else + __sync_synchronize(); + return value_ == rhs; +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator!= (T rhs) const { - return (this->value_ != rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) != rhs; +#else + __sync_synchronize(); + return value_ != rhs; +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator>= (T rhs) const { - return (this->value_ >= rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) >= rhs; +#else + __sync_synchronize(); + return value_ >= rhs; +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator> (T rhs) const { - return (this->value_ > rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) > rhs; +#else + __sync_synchronize(); + return value_ > rhs; +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator<= (T rhs) const { - return (this->value_ <= rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) <= rhs; +#else + __sync_synchronize(); + return value_ <= rhs; +#endif } template <typename T> ACE_INLINE bool ACE_Atomic_Op_GCC<T>::operator< (T rhs) const { - return (this->value_ < rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME) < rhs; +#else + __sync_synchronize(); + return value_ < rhs; +#endif } template <typename T> ACE_INLINE ACE_Atomic_Op_GCC<T> & ACE_Atomic_Op_GCC<T>::operator= (T rhs) { - (void) __sync_lock_test_and_set (&this->value_, rhs); +#if defined (USE_GCC_CPP11_ATOMICS) + __atomic_store_n (&value_, rhs, __ATOMIC_RELEASE); +#else + (void) __sync_lock_test_and_set (&value_, rhs); +#endif return *this; } @@ -122,7 +185,11 @@ ACE_INLINE ACE_Atomic_Op_GCC<T> & ACE_Atomic_Op_GCC<T>::operator= ( const ACE_Atomic_Op_GCC<T> &rhs) { - (void) __sync_lock_test_and_set (&this->value_, rhs.value_); +#if defined (USE_GCC_CPP11_ATOMICS) + __atomic_store_n (&value_, __atomic_load_n (&rhs.value_, __ATOMIC_CONSUME), __ATOMIC_RELEASE); +#else + (void) __sync_lock_test_and_set (&value_, rhs.value_); +#endif return *this; } @@ -130,23 +197,34 @@ template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::exchange (T newval) { - return __sync_val_compare_and_swap (&this->value_, this->value_, newval); +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_exchange_n (&value_, newval, __ATOMIC_ACQ_REL); +#else + return __sync_val_compare_and_swap (&value_, value_, newval); +#endif } template <typename T> ACE_INLINE T ACE_Atomic_Op_GCC<T>::value (void) const { - return this->value_; +#if defined (USE_GCC_CPP11_ATOMICS) + return __atomic_load_n (&value_, __ATOMIC_CONSUME); +#else + __sync_synchronize(); + return value_; +#endif } template <typename T> ACE_INLINE volatile T & ACE_Atomic_Op_GCC<T>::value_i (void) { - return this->value_; + return value_; } +#undef USE_GCC_CPP11_ATOMICS + ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_HAS_GCC_ATOMIC_BUILTINS */ |