From fe42aa0b9d11fafeae17bbc04d690c9c0ede0537 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 10 May 2017 09:58:28 -0400 Subject: [PATCH] Bug 1363426 - part 1 - remove #ifdeffery in Atomics.h; r=erahm Every platform where we use GCC has , so there's no need to use GCC-specific __sync* intrinsics anymore. The header may generate better code for several operations, as well. --- mfbt/Atomics.h | 213 +------------------------------------------------ 1 file changed, 1 insertion(+), 212 deletions(-) diff --git a/mfbt/Atomics.h b/mfbt/Atomics.h index 213d1b9f07dd..417eab2b481c 100644 --- a/mfbt/Atomics.h +++ b/mfbt/Atomics.h @@ -164,10 +164,7 @@ enum MemoryOrdering { } // namespace mozilla -// Build up the underlying intrinsics. -#ifdef MOZ_HAVE_CXX11_ATOMICS - -# include +#include namespace mozilla { namespace detail { @@ -326,214 +323,6 @@ struct ToStorageTypeArgument static constexpr T convert (T aT) { return aT; } }; -} // namespace detail -} // namespace mozilla - -#elif defined(__GNUC__) - -namespace mozilla { -namespace detail { - -/* - * The __sync_* family of intrinsics is documented here: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html - * - * While these intrinsics are deprecated in favor of the newer __atomic_* - * family of intrincs: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html - * - * any GCC version that supports the __atomic_* intrinsics will also support - * the header and so will be handled above. We provide a version of - * atomics using the __sync_* intrinsics to support older versions of GCC. - * - * All __sync_* intrinsics that we use below act as full memory barriers, for - * both compiler and hardware reordering, except for __sync_lock_test_and_set, - * which is a only an acquire barrier. When we call __sync_lock_test_and_set, - * we add a barrier above it as appropriate. - */ - -template struct Barrier; - -/* - * Some processors (in particular, x86) don't require quite so many calls to - * __sync_sychronize as our specializations of Barrier produce. If - * performance turns out to be an issue, defining these specializations - * on a per-processor basis would be a good first tuning step. - */ - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() { __sync_synchronize(); } - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() { __sync_synchronize(); } -}; - -template::value> -struct AtomicStorageType -{ - // For non-enums, just use the type directly. - typedef T Type; -}; - -template -struct AtomicStorageType - : Conditional -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "wrong type computed in conditional above"); -}; - -template -struct IntrinsicMemoryOps -{ - typedef typename AtomicStorageType::Type ValueType; - - static T load(const ValueType& aPtr) - { - Barrier::beforeLoad(); - T val = T(aPtr); - Barrier::afterLoad(); - return val; - } - - static void store(ValueType& aPtr, T aVal) - { - Barrier::beforeStore(); - aPtr = ValueType(aVal); - Barrier::afterStore(); - } - - static T exchange(ValueType& aPtr, T aVal) - { - // __sync_lock_test_and_set is only an acquire barrier; loads and stores - // can't be moved up from after to before it, but they can be moved down - // from before to after it. We may want a stricter ordering, so we need - // an explicit barrier. - Barrier::beforeStore(); - return T(__sync_lock_test_and_set(&aPtr, ValueType(aVal))); - } - - static bool compareExchange(ValueType& aPtr, T aOldVal, T aNewVal) - { - return __sync_bool_compare_and_swap(&aPtr, ValueType(aOldVal), ValueType(aNewVal)); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - static T add(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_add(&aPtr, ValueType(aVal))); - } - - static T sub(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_sub(&aPtr, ValueType(aVal))); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - /* - * The reinterpret_casts are needed so that - * __sync_fetch_and_{add,sub} will properly type-check. - * - * Also, these functions do not provide standard semantics for - * pointer types, so we need to adjust the addend. - */ - static ValueType add(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_add(&aPtr, amount); - } - - static ValueType sub(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_sub(&aPtr, amount); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicAddSub Base; - typedef typename Base::ValueType ValueType; - - static T inc(ValueType& aPtr) { return Base::add(aPtr, 1); } - static T dec(ValueType& aPtr) { return Base::sub(aPtr, 1); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ - static T or_( T& aPtr, T aVal) { return __sync_fetch_and_or(&aPtr, aVal); } - static T xor_(T& aPtr, T aVal) { return __sync_fetch_and_xor(&aPtr, aVal); } - static T and_(T& aPtr, T aVal) { return __sync_fetch_and_and(&aPtr, aVal); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ -}; - -template::value> -struct ToStorageTypeArgument -{ - typedef typename AtomicStorageType::Type ResultType; - - static constexpr ResultType convert (T aT) { return ResultType(aT); } -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#else -# error "Atomic compiler intrinsics are not supported on your platform" -#endif - -namespace mozilla { - -namespace detail { - template class AtomicBase {