summaryrefslogtreecommitdiff
path: root/boost/atomic/detail/ops_msvc_x86.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/atomic/detail/ops_msvc_x86.hpp')
-rw-r--r--boost/atomic/detail/ops_msvc_x86.hpp57
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 > > >
{
};