From c196e6da0cd559fdbd1b93546d58a067209dca1b Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 11 May 2014 14:18:49 +0400 Subject: [PATCH] Fixed compilation of ARM backend. Simplified fences implementation. --- include/boost/atomic/detail/ops_gcc_arm.hpp | 78 +++++----------- include/boost/atomic/detail/ops_gcc_ppc.hpp | 41 +++------ include/boost/atomic/detail/ops_gcc_sparc.hpp | 56 ++++-------- include/boost/atomic/detail/ops_gcc_sync.hpp | 88 ++++++------------- include/boost/atomic/detail/ops_gcc_x86.hpp | 83 ++--------------- include/boost/atomic/detail/ops_linux_arm.hpp | 44 +--------- include/boost/atomic/detail/platform.hpp | 4 +- 7 files changed, 91 insertions(+), 303 deletions(-) diff --git a/include/boost/atomic/detail/ops_gcc_arm.hpp b/include/boost/atomic/detail/ops_gcc_arm.hpp index d3e9e07..12ce7b7 100644 --- a/include/boost/atomic/detail/ops_gcc_arm.hpp +++ b/include/boost/atomic/detail/ops_gcc_arm.hpp @@ -92,28 +92,14 @@ struct gcc_arm_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & memory_order_release) != 0) hardware_full_fence(); - break; - default:; - } } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & memory_order_acquire) != 0) hardware_full_fence(); - break; - default:; - } } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT @@ -278,7 +264,7 @@ struct operations< 4u, Signed > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -304,7 +290,7 @@ struct operations< 4u, Signed > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -330,7 +316,7 @@ struct operations< 4u, Signed > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -356,7 +342,7 @@ struct operations< 4u, Signed > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -382,7 +368,7 @@ struct operations< 4u, Signed > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -433,7 +419,7 @@ struct operations< 1u, false > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -460,7 +446,7 @@ struct operations< 1u, false > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -495,7 +481,7 @@ struct operations< 1u, true > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -522,7 +508,7 @@ struct operations< 1u, true > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -558,7 +544,7 @@ struct operations< 2u, false > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -585,7 +571,7 @@ struct operations< 2u, false > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -620,7 +606,7 @@ struct operations< 2u, true > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -647,7 +633,7 @@ struct operations< 2u, true > : [result] "=&r" (result), // %1 [tmp] "=&l" (tmp), // %2 [storage] "+Q" (storage) // %3 - : [value] "r" (v), // %4 + : [value] "r" (v) // %4 : "cc" ); fence_after(order); @@ -671,7 +657,7 @@ struct operations< 2u, true > : template< bool Signed > struct operations< 8u, Signed > : - public gcc_ppc_operations_base + public gcc_arm_operations_base { typedef typename make_storage_type< 8u, Signed >::type storage_type; @@ -690,7 +676,7 @@ struct operations< 8u, Signed > : "ldrexd %1, %H1, %2\n" BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) : "=&l" (tmp), // %0 - "=&r" (original), // %1 + "=&r" (original) // %1 : "Q" (storage) // %2 ); fence_after(order); @@ -815,7 +801,7 @@ struct operations< 8u, Signed > : "=&r" (result), // %1 "=&l" (tmp), // %2 "+Q" (storage) // %3 - : "r" (v), // %4 + : "r" (v) // %4 : "cc" ); fence_after(order); @@ -842,7 +828,7 @@ struct operations< 8u, Signed > : "=&r" (result), // %1 "=&l" (tmp), // %2 "+Q" (storage) // %3 - : "r" (v), // %4 + : "r" (v) // %4 : "cc" ); fence_after(order); @@ -869,7 +855,7 @@ struct operations< 8u, Signed > : "=&r" (result), // %1 "=&l" (tmp), // %2 "+Q" (storage) // %3 - : "r" (v), // %4 + : "r" (v) // %4 : "cc" ); fence_after(order); @@ -896,7 +882,7 @@ struct operations< 8u, Signed > : "=&r" (result), // %1 "=&l" (tmp), // %2 "+Q" (storage) // %3 - : "r" (v), // %4 + : "r" (v) // %4 : "cc" ); fence_after(order); @@ -923,7 +909,7 @@ struct operations< 8u, Signed > : "=&r" (result), // %1 "=&l" (tmp), // %2 "+Q" (storage) // %3 - : "r" (v), // %4 + : "r" (v) // %4 : "cc" ); fence_after(order); @@ -951,30 +937,14 @@ struct operations< 8u, Signed > : BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & (memory_order_acquire | memory_order_release)) != 0) gcc_arm_operations_base::hardware_full_fence(); - break; - default:; - } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & ~memory_order_consume) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } } // namespace detail diff --git a/include/boost/atomic/detail/ops_gcc_ppc.hpp b/include/boost/atomic/detail/ops_gcc_ppc.hpp index 528e275..278c7ed 100644 --- a/include/boost/atomic/detail/ops_gcc_ppc.hpp +++ b/include/boost/atomic/detail/ops_gcc_ppc.hpp @@ -77,38 +77,29 @@ struct gcc_ppc_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_release: - case memory_order_acq_rel: #if defined(__powerpc64__) - __asm__ __volatile__ ("lwsync" ::: "memory"); - break; -#endif - case memory_order_seq_cst: + if (order == memory_order_seq_cst) __asm__ __volatile__ ("sync" ::: "memory"); - default:; - } + else if ((order & memory_order_release) != 0) + __asm__ __volatile__ ("lwsync" ::: "memory"); +#else + if ((order & memory_order_release) != 0) + __asm__ __volatile__ ("sync" ::: "memory"); +#endif } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("isync"); - case memory_order_consume: + if ((order & memory_order_acquire) != 0) + __asm__ __volatile__ ("isync" ::: "memory"); + else if (order == memory_order_consume) __asm__ __volatile__ ("" ::: "memory"); - default:; - } } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) - __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("sync" ::: "memory"); } }; @@ -766,16 +757,8 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & ~memory_order_consume) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } } // namespace detail diff --git a/include/boost/atomic/detail/ops_gcc_sparc.hpp b/include/boost/atomic/detail/ops_gcc_sparc.hpp index b444d58..bbeaca1 100644 --- a/include/boost/atomic/detail/ops_gcc_sparc.hpp +++ b/include/boost/atomic/detail/ops_gcc_sparc.hpp @@ -36,39 +36,18 @@ struct gcc_sparc_cas_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); - break; - case memory_order_seq_cst: + if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); - break; - } + else if ((order & memory_order_release) != 0) + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_consume: - case memory_order_release: - break; - case memory_order_acquire: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); - break; - case memory_order_seq_cst: + if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); - break; - default:; - } + else if ((order & memory_order_acquire) != 0) + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT @@ -76,11 +55,6 @@ struct gcc_sparc_cas_base if (order == memory_order_seq_cst) __asm__ __volatile__ ("membar #Sync" ::: "memory"); } - - static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT - { - fence_after(order); - } }; template< bool Signed > @@ -99,7 +73,7 @@ struct gcc_sparc_cas32 : static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; - fence_after_load(order); + fence_after(order); return v; } @@ -191,7 +165,7 @@ struct gcc_sparc_cas64 : static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; - fence_after_load(order); + fence_after(order); return v; } @@ -237,10 +211,8 @@ struct operations< 8u, Signed > : BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { - switch(order) + switch (order) { - case memory_order_relaxed: - break; case memory_order_release: __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); break; @@ -250,18 +222,20 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT case memory_order_acq_rel: __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); break; - case memory_order_consume: - break; case memory_order_seq_cst: __asm__ __volatile__ ("membar #Sync" ::: "memory"); break; - default:; + case memory_order_consume: + case memory_order_relaxed: + default: + break; } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - __asm__ __volatile__ ("" ::: "memory"); + if ((order & ~memory_order_consume) != 0) + __asm__ __volatile__ ("" ::: "memory"); } } // namespace detail diff --git a/include/boost/atomic/detail/ops_gcc_sync.hpp b/include/boost/atomic/detail/ops_gcc_sync.hpp index 695e079..e51b9e6 100644 --- a/include/boost/atomic/detail/ops_gcc_sync.hpp +++ b/include/boost/atomic/detail/ops_gcc_sync.hpp @@ -31,8 +31,30 @@ namespace boost { namespace atomics { namespace detail { +struct gcc_sync_operations_base +{ + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT + { + if ((order & memory_order_release) != 0) + __sync_synchronize(); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __sync_synchronize(); + } + + static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT + { + if ((order & (memory_order_acquire | memory_order_consume)) != 0) + __sync_synchronize(); + } +}; + template< typename T > -struct gcc_sync_operations +struct gcc_sync_operations : + public gcc_sync_operations_base { typedef T storage_type; @@ -126,45 +148,6 @@ struct gcc_sync_operations { return true; } - -private: - static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT - { - switch (order) - { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; - } - } - - static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT - { - if (order == memory_order_seq_cst) - __sync_synchronize(); - } - - static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT - { - switch (order) - { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; - } - } }; #if BOOST_ATOMIC_INT8_LOCK_FREE > 0 @@ -237,35 +220,14 @@ struct operations< 16u, Signed > : BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - break; - case memory_order_release: - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: + if (order != memory_order_relaxed) __sync_synchronize(); - break; - } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_consume: - break; - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & ~memory_order_consume) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } } // namespace detail diff --git a/include/boost/atomic/detail/ops_gcc_x86.hpp b/include/boost/atomic/detail/ops_gcc_x86.hpp index 8a1d7c5..acbe9bc 100644 --- a/include/boost/atomic/detail/ops_gcc_x86.hpp +++ b/include/boost/atomic/detail/ops_gcc_x86.hpp @@ -44,61 +44,14 @@ struct gcc_x86_operations_base { static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: + if ((order & memory_order_release) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_acquire: - case memory_order_acq_rel: + if ((order & memory_order_acquire) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - case memory_order_consume: - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } - } - - static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT - { - switch (order) - { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_acquire: - case memory_order_acq_rel: - __asm__ __volatile__ ("" ::: "memory"); - break; - case memory_order_consume: - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } }; @@ -125,7 +78,7 @@ struct gcc_x86_operations : static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT { storage_type v = storage; - fence_after_load(order); + fence_after(order); return v; } @@ -750,17 +703,8 @@ struct operations< 16u, Signed > : BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) + if (order == memory_order_seq_cst) { - case memory_order_relaxed: - case memory_order_consume: - break; - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - __asm__ __volatile__ ("" ::: "memory"); - break; - case memory_order_seq_cst: __asm__ __volatile__ ( #if defined(__x86_64__) || defined(__SSE2__) @@ -770,26 +714,17 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT #endif ::: "memory" ); - break; - default:; + } + else if ((order & (memory_order_acquire | memory_order_release)) != 0) + { + __asm__ __volatile__ ("" ::: "memory"); } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_consume: - break; - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & ~memory_order_consume) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } } // namespace detail diff --git a/include/boost/atomic/detail/ops_linux_arm.hpp b/include/boost/atomic/detail/ops_linux_arm.hpp index 8c393df..e695297 100644 --- a/include/boost/atomic/detail/ops_linux_arm.hpp +++ b/include/boost/atomic/detail/ops_linux_arm.hpp @@ -59,16 +59,8 @@ struct linux_arm_cas_base { static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & memory_order_release) != 0) hardware_full_fence(); - break; - case memory_order_consume: - default:; - } } static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT @@ -79,15 +71,8 @@ struct linux_arm_cas_base static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & memory_order_acquire) != 0) hardware_full_fence(); - break; - default:; - } } static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT @@ -175,35 +160,14 @@ struct operations< 4u, Signed > : BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - break; - case memory_order_release: - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & (memory_order_acquire | memory_order_release)) != 0) linux_arm_cas_base::hardware_full_fence(); - break; - } } BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT { - switch (order) - { - case memory_order_relaxed: - case memory_order_consume: - break; - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: + if ((order & ~memory_order_consume) != 0) __asm__ __volatile__ ("" ::: "memory"); - break; - default:; - } } } // namespace detail diff --git a/include/boost/atomic/detail/platform.hpp b/include/boost/atomic/detail/platform.hpp index d53b2ad..1fbd344 100644 --- a/include/boost/atomic/detail/platform.hpp +++ b/include/boost/atomic/detail/platform.hpp @@ -25,13 +25,13 @@ #define BOOST_ATOMIC_DETAIL_PLATFORM emulated #define BOOST_ATOMIC_EMULATED - +/* // Intel compiler does not support __atomic* intrinsics properly, although defines them (tested with 13.0.1 and 13.1.1 on Linux) #elif (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(BOOST_INTEL_CXX_VERSION))\ || (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302)) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_atomic - +*/ #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_x86