diff --git a/include/boost/atomic/detail/atomic_template.hpp b/include/boost/atomic/detail/atomic_template.hpp index a4daff0..b70f1c9 100644 --- a/include/boost/atomic/detail/atomic_template.hpp +++ b/include/boost/atomic/detail/atomic_template.hpp @@ -51,8 +51,9 @@ BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order deduce_failure_order(memory_order BOOST_FORCEINLINE BOOST_CONSTEXPR bool cas_failure_order_must_not_be_stronger_than_success_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { - return ((failure_order | success_order) & ~memory_order_consume) == (success_order & ~memory_order_consume) - && (failure_order & memory_order_consume) <= (success_order & memory_order_consume); + // 15 == (memory_order_seq_cst | memory_order_consume), see memory_order.hpp + // Given the enum values we can test the strength of memory order requirements with this single condition. + return (failure_order & 15u) <= (success_order & 15u); } template< typename T, bool IsInt = boost::is_integral< T >::value > diff --git a/include/boost/atomic/detail/ops_msvc_arm.hpp b/include/boost/atomic/detail/ops_msvc_arm.hpp index bde1e78..25d82aa 100644 --- a/include/boost/atomic/detail/ops_msvc_arm.hpp +++ b/include/boost/atomic/detail/ops_msvc_arm.hpp @@ -81,7 +81,7 @@ struct msvc_arm_operations_base static BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order cas_common_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT { // Combine order flags together and transform memory_order_consume to memory_order_acquire - return static_cast< memory_order >(((failure_order | success_order) & ~memory_order_consume) | (((failure_order | success_order) & memory_order_consume) >> 3u)); + return static_cast< memory_order >(((failure_order | success_order) & ~memory_order_consume) | (((failure_order | success_order) & memory_order_consume) << 1u)); } }; diff --git a/include/boost/memory_order.hpp b/include/boost/memory_order.hpp index 4945af6..fbe9034 100644 --- a/include/boost/memory_order.hpp +++ b/include/boost/memory_order.hpp @@ -37,15 +37,19 @@ namespace boost // // if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... } // +// The values are also in the order of increasing "strength" +// of the fences so that success/failure orders can be checked +// efficiently in compare_exchange methods. +// enum memory_order { memory_order_relaxed = 0, - memory_order_acquire = 1, - memory_order_release = 2, - memory_order_acq_rel = 3, // acquire | release - memory_order_seq_cst = 7, // acq_rel | 4 - memory_order_consume = 8 + memory_order_consume = 1, + memory_order_acquire = 2, + memory_order_release = 4, + memory_order_acq_rel = 6, // acquire | release + memory_order_seq_cst = 14 // acq_rel | 8 }; } // namespace boost