From 6aed631bd0460d640b59bc8099a00bbbcd208e1a Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Fri, 21 Dec 2012 21:30:41 +0000 Subject: [PATCH] Attempt to fix compilation on Windows CE. Restored full fence in the platform_fence_after_load function on architectures other than x86 and x86_64. The fence is not required only on those architectures. [SVN r82157] --- include/boost/atomic/detail/interlocked.hpp | 6 +++--- include/boost/atomic/detail/windows.hpp | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/boost/atomic/detail/interlocked.hpp b/include/boost/atomic/detail/interlocked.hpp index 5b2c111..84a7131 100644 --- a/include/boost/atomic/detail/interlocked.hpp +++ b/include/boost/atomic/detail/interlocked.hpp @@ -18,9 +18,9 @@ #include -#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) -#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) BOOST_INTERLOCKED_EXCHANGE(dest, newval) -#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) BOOST_INTERLOCKED_EXCHANGE_ADD(dest, addend) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), exchange, compare) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) BOOST_INTERLOCKED_EXCHANGE((long*)(dest), newval) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) BOOST_INTERLOCKED_EXCHANGE_ADD((long*)(dest), addend) #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, newval) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset)) diff --git a/include/boost/atomic/detail/windows.hpp b/include/boost/atomic/detail/windows.hpp index c0cbf9f..4c401ae 100644 --- a/include/boost/atomic/detail/windows.hpp +++ b/include/boost/atomic/detail/windows.hpp @@ -42,7 +42,7 @@ extern "C" void _mm_mfence(void); #pragma intrinsic(_mm_mfence) #endif -BOOST_FORCEINLINE void x86_full_fence(void) +BOOST_FORCEINLINE void hardware_full_fence(void) { #if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) // Use mfence only if SSE2 is available @@ -54,13 +54,10 @@ BOOST_FORCEINLINE void x86_full_fence(void) } // Define compiler barriers -#if defined(_MSC_VER) && _MSC_VER >= 1310 - +#if defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE) extern "C" void _ReadWriteBarrier(); #pragma intrinsic(_ReadWriteBarrier) - #define BOOST_ATOMIC_READ_WRITE_BARRIER() _ReadWriteBarrier() - #endif #ifndef BOOST_ATOMIC_READ_WRITE_BARRIER @@ -95,6 +92,17 @@ BOOST_FORCEINLINE void platform_fence_after_load(memory_order order) { BOOST_ATOMIC_READ_WRITE_BARRIER(); + + // On x86 and x86_64 there is no need for a hardware barrier, + // even if seq_cst memory order is requested, because all + // seq_cst writes are implemented with lock-prefixed operations + // or xchg which has implied lock prefix. Therefore normal loads + // are already ordered with seq_cst stores on these architectures. + +#if !(defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))) + if (order == memory_order_seq_cst) + hardware_full_fence(); +#endif } } // namespace detail @@ -106,7 +114,7 @@ atomic_thread_fence(memory_order order) { BOOST_ATOMIC_READ_WRITE_BARRIER(); if (order == memory_order_seq_cst) - atomics::detail::x86_full_fence(); + atomics::detail::hardware_full_fence(); } #define BOOST_ATOMIC_SIGNAL_FENCE 2