diff options
Diffstat (limited to 'boost/atomic/detail/ops_msvc_x86.hpp')
-rw-r--r-- | boost/atomic/detail/ops_msvc_x86.hpp | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/boost/atomic/detail/ops_msvc_x86.hpp b/boost/atomic/detail/ops_msvc_x86.hpp index 501d9c622d..589c029864 100644 --- a/boost/atomic/detail/ops_msvc_x86.hpp +++ b/boost/atomic/detail/ops_msvc_x86.hpp @@ -166,6 +166,7 @@ struct operations< 4u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -237,6 +238,7 @@ struct operations< 1u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -281,6 +283,7 @@ struct operations< 1u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { @@ -421,6 +424,7 @@ struct operations< 2u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -465,6 +469,7 @@ struct operations< 2u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { @@ -604,6 +609,7 @@ template< bool Signed > 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; // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations: // @@ -611,10 +617,12 @@ struct msvc_dcas_x86 // * Reading or writing a quadword aligned on a 64-bit boundary // // Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations - // have at least 8 byte alignment. The only unfortunate case is when atomic is placeod on the stack and it is not 8-byte aligned (like on 32 bit Windows). + // have at least 8 byte alignment. The only unfortunate case is when atomic is placed on the stack and it is not 8-byte aligned (like on 32 bit Windows). static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + storage_type volatile* p = &storage; if (((uint32_t)p & 0x00000007) == 0) { @@ -661,10 +669,14 @@ struct msvc_dcas_x86 mov ebx, backup }; } + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); } static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + storage_type const volatile* p = &storage; storage_type value; @@ -710,18 +722,23 @@ struct msvc_dcas_x86 }; } + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + return value; } static BOOST_FORCEINLINE bool compare_exchange_strong( storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT { + // MSVC-11 in 32-bit mode sometimes generates messed up code without compiler barriers, + // even though the _InterlockedCompareExchange64 intrinsic already provides one. + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + storage_type volatile* p = &storage; #if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) const storage_type old_val = (storage_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(p, desired, expected); const bool result = (old_val == expected); expected = old_val; - return result; #else bool result; int backup; @@ -740,8 +757,10 @@ struct msvc_dcas_x86 mov ebx, backup sete result }; - return result; #endif + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + return result; } static BOOST_FORCEINLINE bool compare_exchange_weak( @@ -750,6 +769,34 @@ 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 + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + storage_type volatile* p = &storage; + int backup; + __asm + { + mov backup, ebx + mov edi, p + mov ebx, dword ptr [v] + mov ecx, dword ptr [v + 4] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + 4] + align 16 + again: + lock cmpxchg8b qword ptr [edi] + jne again + mov ebx, backup + mov dword ptr [v], eax + mov dword ptr [v + 4], edx + }; + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + return v; + } + static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT { return true; @@ -770,6 +817,7 @@ struct operations< 8u, Signed > : { typedef msvc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type; typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -814,6 +862,7 @@ template< bool Signed > 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_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -848,7 +897,7 @@ struct msvc_dcas_x86_64 template< bool Signed > struct operations< 16u, Signed > : - public cas_based_operations< msvc_dcas_x86_64< Signed > > + public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed > > > { }; |