From e4506534510635ff45d2d46dd9e9b53273c8d4c8 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Thu, 15 Sep 2016 01:05:51 +0300 Subject: [PATCH] Extracted x86 mfence detection to caps headers. Also, for non-gcc compilers which do not allow to auto-detect mfence availability (e.g. Oracle Studio) the instruction is assumed to be supported (since SSE2 is supported by virtually every x86 CPU now). This can be changed by defining BOOST_ATOMIC_NO_MFENCE. --- include/boost/atomic/detail/caps_gcc_x86.hpp | 9 +++++++++ include/boost/atomic/detail/caps_msvc_x86.hpp | 5 +++++ include/boost/atomic/detail/ops_gcc_x86.hpp | 2 +- include/boost/atomic/detail/ops_msvc_x86.hpp | 5 ++--- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/boost/atomic/detail/caps_gcc_x86.hpp b/include/boost/atomic/detail/caps_gcc_x86.hpp index f6c91eb..7485b01 100644 --- a/include/boost/atomic/detail/caps_gcc_x86.hpp +++ b/include/boost/atomic/detail/caps_gcc_x86.hpp @@ -37,6 +37,11 @@ #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif +#if defined(__x86_64__) || defined(__SSE2__) +// Use mfence only if SSE2 is available +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + #else // defined(__GNUC__) #if defined(__i386__) && !defined(BOOST_ATOMIC_NO_CMPXCHG8B) @@ -47,6 +52,10 @@ #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif +#if !defined(BOOST_ATOMIC_NO_MFENCE) +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + #endif // defined(__GNUC__) #define BOOST_ATOMIC_INT8_LOCK_FREE 2 diff --git a/include/boost/atomic/detail/caps_msvc_x86.hpp b/include/boost/atomic/detail/caps_msvc_x86.hpp index 5661a5b..2ee4c92 100644 --- a/include/boost/atomic/detail/caps_msvc_x86.hpp +++ b/include/boost/atomic/detail/caps_msvc_x86.hpp @@ -30,6 +30,11 @@ #define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 #endif +#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 +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + #define BOOST_ATOMIC_INT8_LOCK_FREE 2 #define BOOST_ATOMIC_INT16_LOCK_FREE 2 #define BOOST_ATOMIC_INT32_LOCK_FREE 2 diff --git a/include/boost/atomic/detail/ops_gcc_x86.hpp b/include/boost/atomic/detail/ops_gcc_x86.hpp index f68125c..a4e4af3 100644 --- a/include/boost/atomic/detail/ops_gcc_x86.hpp +++ b/include/boost/atomic/detail/ops_gcc_x86.hpp @@ -485,7 +485,7 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { __asm__ __volatile__ ( -#if defined(__x86_64__) || defined(__SSE2__) +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) "mfence\n" #else "lock; addl $0, (%%esp)\n" diff --git a/include/boost/atomic/detail/ops_msvc_x86.hpp b/include/boost/atomic/detail/ops_msvc_x86.hpp index 589c029..04b496e 100644 --- a/include/boost/atomic/detail/ops_msvc_x86.hpp +++ b/include/boost/atomic/detail/ops_msvc_x86.hpp @@ -42,7 +42,7 @@ #pragma warning(disable: 4731) #endif -#if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) extern "C" void _mm_mfence(void); #if defined(BOOST_MSVC) #pragma intrinsic(_mm_mfence) @@ -74,8 +74,7 @@ struct msvc_x86_operations_base { static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT { -#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 +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) _mm_mfence(); #else long tmp;