diff options
Diffstat (limited to 'boost/atomic/detail')
-rw-r--r-- | boost/atomic/detail/atomic_template.hpp | 16 | ||||
-rw-r--r-- | boost/atomic/detail/config.hpp | 5 | ||||
-rw-r--r-- | boost/atomic/detail/ops_emulated.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_alpha.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_arm.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_atomic.hpp | 5 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_ppc.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_sparc.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_sync.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_x86.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_gcc_x86_dcas.hpp | 29 | ||||
-rw-r--r-- | boost/atomic/detail/ops_linux_arm.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_msvc_arm.hpp | 2 | ||||
-rw-r--r-- | boost/atomic/detail/ops_msvc_x86.hpp | 8 | ||||
-rw-r--r-- | boost/atomic/detail/ops_windows.hpp | 2 |
15 files changed, 65 insertions, 18 deletions
diff --git a/boost/atomic/detail/atomic_template.hpp b/boost/atomic/detail/atomic_template.hpp index 2deaded62f..dd3c741506 100644 --- a/boost/atomic/detail/atomic_template.hpp +++ b/boost/atomic/detail/atomic_template.hpp @@ -78,9 +78,9 @@ class base_atomic< T, int > private: typedef T value_type; typedef T difference_type; - typedef atomics::detail::operations< storage_size_of< value_type >::value, boost::is_signed< T >::value > operations; protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, boost::is_signed< T >::value > operations; typedef value_type value_arg_type; public: @@ -234,9 +234,9 @@ class base_atomic< bool, int > { private: typedef bool value_type; - typedef atomics::detail::operations< 1u, false > operations; protected: + typedef atomics::detail::operations< 1u, false > operations; typedef value_type value_arg_type; public: @@ -321,9 +321,9 @@ class base_atomic< T, void > { private: typedef T value_type; - typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; typedef value_type const& value_arg_type; public: @@ -410,9 +410,9 @@ class base_atomic< T*, void* > private: typedef T* value_type; typedef std::ptrdiff_t difference_type; - typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; typedef value_type value_arg_type; public: @@ -540,9 +540,9 @@ class base_atomic< void*, void* > private: typedef void* value_type; typedef std::ptrdiff_t difference_type; - typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; typedef value_type value_arg_type; public: @@ -677,6 +677,9 @@ public: typedef typename base_type::storage_type storage_type; public: + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = base_type::operations::is_always_lock_free; + +public: BOOST_DEFAULTED_FUNCTION(atomic(), BOOST_NOEXCEPT {}) // NOTE: The constructor is made explicit because gcc 4.7 complains that @@ -706,6 +709,9 @@ public: BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile) }; +template< typename T > +BOOST_CONSTEXPR_OR_CONST bool atomic< T >::is_always_lock_free; + typedef atomic< char > atomic_char; typedef atomic< unsigned char > atomic_uchar; typedef atomic< signed char > atomic_schar; diff --git a/boost/atomic/detail/config.hpp b/boost/atomic/detail/config.hpp index 489281c2b4..00f7bff696 100644 --- a/boost/atomic/detail/config.hpp +++ b/boost/atomic/detail/config.hpp @@ -60,14 +60,15 @@ #define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA #endif -#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 403) +#if ((defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 403)) ||\ + defined(__SUNPRO_CC) // This macro indicates we're using older binutils that don't support implied zero displacements for memory opereands, // making code like this invalid: // movl 4+(%%edx), %%eax #define BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS #endif -#if defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) +#if defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) || defined(__SUNPRO_CC) // This macro indicates that the compiler does not support allocating rax:rdx register pairs ("A") in asm blocks #define BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS #endif diff --git a/boost/atomic/detail/ops_emulated.hpp b/boost/atomic/detail/ops_emulated.hpp index 17032917fe..a21128ec69 100644 --- a/boost/atomic/detail/ops_emulated.hpp +++ b/boost/atomic/detail/ops_emulated.hpp @@ -35,6 +35,8 @@ struct emulated_operations { typedef T storage_type; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = false; + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { lockpool::scoped_lock lock(&storage); diff --git a/boost/atomic/detail/ops_gcc_alpha.hpp b/boost/atomic/detail/ops_gcc_alpha.hpp index 3c0e258ceb..15118f58a2 100644 --- a/boost/atomic/detail/ops_gcc_alpha.hpp +++ b/boost/atomic/detail/ops_gcc_alpha.hpp @@ -63,6 +63,8 @@ namespace detail { struct gcc_alpha_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) diff --git a/boost/atomic/detail/ops_gcc_arm.hpp b/boost/atomic/detail/ops_gcc_arm.hpp index d2c2f39a2c..e181b16853 100644 --- a/boost/atomic/detail/ops_gcc_arm.hpp +++ b/boost/atomic/detail/ops_gcc_arm.hpp @@ -100,6 +100,8 @@ namespace detail { struct gcc_arm_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) diff --git a/boost/atomic/detail/ops_gcc_atomic.hpp b/boost/atomic/detail/ops_gcc_atomic.hpp index 573a695d08..0a34c01f16 100644 --- a/boost/atomic/detail/ops_gcc_atomic.hpp +++ b/boost/atomic/detail/ops_gcc_atomic.hpp @@ -85,6 +85,11 @@ struct gcc_atomic_operations { typedef T storage_type; + // Note: In the current implementation, gcc_atomic_operations are used onlu when the particularly sized __atomic + // intrinsics are always lock-free (i.e. the corresponding LOCK_FREE macro is 2). Therefore it is safe to + // always set is_always_lock_free to true here. + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { __atomic_store_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); diff --git a/boost/atomic/detail/ops_gcc_ppc.hpp b/boost/atomic/detail/ops_gcc_ppc.hpp index 9131791193..4183bc0485 100644 --- a/boost/atomic/detail/ops_gcc_ppc.hpp +++ b/boost/atomic/detail/ops_gcc_ppc.hpp @@ -85,6 +85,8 @@ namespace detail { struct gcc_ppc_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { #if defined(__powerpc64__) || defined(__PPC64__) diff --git a/boost/atomic/detail/ops_gcc_sparc.hpp b/boost/atomic/detail/ops_gcc_sparc.hpp index faefecaf76..fd42fa8095 100644 --- a/boost/atomic/detail/ops_gcc_sparc.hpp +++ b/boost/atomic/detail/ops_gcc_sparc.hpp @@ -34,6 +34,8 @@ namespace detail { struct gcc_sparc_cas_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) diff --git a/boost/atomic/detail/ops_gcc_sync.hpp b/boost/atomic/detail/ops_gcc_sync.hpp index 87f2f53029..2f41aff279 100644 --- a/boost/atomic/detail/ops_gcc_sync.hpp +++ b/boost/atomic/detail/ops_gcc_sync.hpp @@ -33,6 +33,8 @@ namespace detail { struct gcc_sync_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) diff --git a/boost/atomic/detail/ops_gcc_x86.hpp b/boost/atomic/detail/ops_gcc_x86.hpp index a4e4af3660..98dcdc064e 100644 --- a/boost/atomic/detail/ops_gcc_x86.hpp +++ b/boost/atomic/detail/ops_gcc_x86.hpp @@ -42,6 +42,8 @@ namespace detail { struct gcc_x86_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) diff --git a/boost/atomic/detail/ops_gcc_x86_dcas.hpp b/boost/atomic/detail/ops_gcc_x86_dcas.hpp index 47cc36d8e7..2f51182e5a 100644 --- a/boost/atomic/detail/ops_gcc_x86_dcas.hpp +++ b/boost/atomic/detail/ops_gcc_x86_dcas.hpp @@ -38,6 +38,8 @@ struct gcc_dcas_x86 typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { if ((((uint32_t)&storage) & 0x00000007) == 0) @@ -367,9 +369,12 @@ struct gcc_dcas_x86_64 typedef typename make_storage_type< 16u, Signed >::type storage_type; typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { uint64_t const* p_value = (uint64_t const*)&v; + const uint64_t v_lo = p_value[0], v_hi = p_value[1]; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( @@ -379,7 +384,7 @@ struct gcc_dcas_x86_64 "1: lock; cmpxchg16b %[dest]\n\t" "jne 1b\n\t" : [dest] "=o" (storage) - : "b" (p_value[0]), "c" (p_value[1]) + : "b" (v_lo), "c" (v_hi) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -391,7 +396,7 @@ struct gcc_dcas_x86_64 "1: lock; cmpxchg16b 0(%[dest])\n\t" "jne 1b\n\t" : - : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage) + : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -466,6 +471,7 @@ struct gcc_dcas_x86_64 #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap uint64_t const* p_desired = (uint64_t const*)&desired; + const uint64_t desired_lo = p_desired[0], desired_hi = p_desired[1]; bool success; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ @@ -477,7 +483,7 @@ struct gcc_dcas_x86_64 "movq %%rax, %[expected]\n\t" "movq %%rdx, 8+%[expected]\n\t" : [dest] "+m" (storage), [expected] "+o" (expected), [success] "=q" (success) - : "b" (p_desired[0]), "c" (p_desired[1]) + : "b" (desired_lo), "c" (desired_hi) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -490,7 +496,7 @@ struct gcc_dcas_x86_64 "movq %%rax, 0(%[expected])\n\t" "movq %%rdx, 8(%[expected])\n\t" : [dest] "+m" (storage), [success] "=q" (success) - : "b" (p_desired[0]), "c" (p_desired[1]), [expected] "r" (&expected) + : "b" (desired_lo), "c" (desired_hi), [expected] "r" (&expected) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -498,6 +504,7 @@ struct gcc_dcas_x86_64 return success; #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) uint64_t const* p_desired = (uint64_t const*)&desired; + const uint64_t desired_lo = p_desired[0], desired_hi = p_desired[1]; bool success; __asm__ __volatile__ ( @@ -505,10 +512,10 @@ struct gcc_dcas_x86_64 "sete %[success]\n\t" #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES) : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success) - : "b,b" (p_desired[0]), "c,c" (p_desired[1]) + : "b,b" (desired_lo), "c,c" (desired_hi) #else : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success) - : "b" (p_desired[0]), "c" (p_desired[1]) + : "b" (desired_lo), "c" (desired_hi) #endif : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); @@ -538,6 +545,7 @@ struct gcc_dcas_x86_64 // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap storage_type old_value; uint64_t const* p_value = (uint64_t const*)&v; + const uint64_t v_lo = p_value[0], v_hi = p_value[1]; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( @@ -549,7 +557,7 @@ struct gcc_dcas_x86_64 "movq %%rax, %[old_value]\n\t" "movq %%rdx, 8+%[old_value]\n\t" : [dest] "+o" (storage), [old_value] "=o" (old_value) - : "b" (p_value[0]), "c" (p_value[1]) + : "b" (v_lo), "c" (v_hi) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -563,7 +571,7 @@ struct gcc_dcas_x86_64 "movq %%rax, 0(%[old_value])\n\t" "movq %%rdx, 8(%[old_value])\n\t" : - : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage), [old_value] "r" (&old_value) + : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage), [old_value] "r" (&old_value) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -571,6 +579,7 @@ struct gcc_dcas_x86_64 return old_value; #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS) uint64_t const* p_value = (uint64_t const*)&v; + const uint64_t v_lo = p_value[0], v_hi = p_value[1]; #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) __asm__ __volatile__ ( @@ -580,7 +589,7 @@ struct gcc_dcas_x86_64 "1: lock; cmpxchg16b %[dest]\n\t" "jne 1b\n\t" : "=&A" (v), [dest] "+o" (storage) - : "b" (p_value[0]), "c" (p_value[1]) + : "b" (v_lo), "c" (v_hi) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) @@ -592,7 +601,7 @@ struct gcc_dcas_x86_64 "1: lock; cmpxchg16b 0(%[dest])\n\t" "jne 1b\n\t" : "=&A" (v) - : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage) + : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS) diff --git a/boost/atomic/detail/ops_linux_arm.hpp b/boost/atomic/detail/ops_linux_arm.hpp index 41713a35f5..01894b63ee 100644 --- a/boost/atomic/detail/ops_linux_arm.hpp +++ b/boost/atomic/detail/ops_linux_arm.hpp @@ -57,6 +57,8 @@ namespace detail { struct linux_arm_cas_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { if ((order & memory_order_release) != 0) diff --git a/boost/atomic/detail/ops_msvc_arm.hpp b/boost/atomic/detail/ops_msvc_arm.hpp index ff953d67e3..fd07f093fb 100644 --- a/boost/atomic/detail/ops_msvc_arm.hpp +++ b/boost/atomic/detail/ops_msvc_arm.hpp @@ -53,6 +53,8 @@ namespace detail { struct msvc_arm_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later diff --git a/boost/atomic/detail/ops_msvc_x86.hpp b/boost/atomic/detail/ops_msvc_x86.hpp index 04b496efb6..24824214dd 100644 --- a/boost/atomic/detail/ops_msvc_x86.hpp +++ b/boost/atomic/detail/ops_msvc_x86.hpp @@ -72,6 +72,8 @@ namespace detail { struct msvc_x86_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) @@ -610,6 +612,8 @@ struct msvc_dcas_x86 typedef typename make_storage_type< 8u, Signed >::type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations: // // The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically: @@ -768,7 +772,7 @@ struct msvc_dcas_x86 return compare_exchange_strong(storage, expected, desired, success_order, failure_order); } - static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); @@ -863,6 +867,8 @@ struct msvc_dcas_x86_64 typedef typename make_storage_type< 16u, Signed >::type storage_type; typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { storage_type value = const_cast< storage_type& >(storage); diff --git a/boost/atomic/detail/ops_windows.hpp b/boost/atomic/detail/ops_windows.hpp index 191eb84d0a..867f1c6113 100644 --- a/boost/atomic/detail/ops_windows.hpp +++ b/boost/atomic/detail/ops_windows.hpp @@ -43,6 +43,8 @@ namespace detail { struct windows_operations_base { + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { long tmp; |