summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Mitz <mitza@objectcomputing.com>2021-09-06 11:23:10 -0500
committerGitHub <noreply@github.com>2021-09-06 11:23:10 -0500
commit106e47365336828900e66d8e33934e0959ef7838 (patch)
tree67f6b1d2d3297ed866c4581747e1d67e3b409bf4
parentd035863b2a8cbf4ddade856ac723bbacecddaeb8 (diff)
parent615284ae6d9ca661bd1f644b042003dd8e161f30 (diff)
downloadATCD-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.inl112
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 */