diff --git a/include/libcopp/utils/atomic_int_type.h b/include/libcopp/utils/atomic_int_type.h index b8478f2..be5d27a 100755 --- a/include/libcopp/utils/atomic_int_type.h +++ b/include/libcopp/utils/atomic_int_type.h @@ -20,6 +20,36 @@ #pragma once +#include "std/explicit_declare.h" + +#if __cplusplus >= 201103L +#include +#elif defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 201402L +#include +#else + +// patch for old gcc +#ifndef __STDC_LIMIT_MACROS +#define _UNDEF__STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif +#ifndef __STDC_CONSTANT_MACROS +#define _UNDEF__STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS +#endif +#include +#include +#ifdef _UNDEF__STDC_LIMIT_MACROS +#undef __STDC_LIMIT_MACROS +#undef _UNDEF__STDC_LIMIT_MACROS +#endif +#ifdef _UNDEF__STDC_CONSTANT_MACROS +#undef __STDC_CONSTANT_MACROS +#undef _UNDEF__STDC_CONSTANT_MACROS +#endif + +#endif + #if defined(__cplusplus) && __cplusplus >= 201103L #include @@ -30,7 +60,7 @@ #include #define __UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD -#elif defined(_MSC_VER) && (_MSC_VER > 1700 || (defined(_HAS_CPP0X) && _HAS_CPP0X)) // VC 11,2012 +#elif defined(_MSC_VER) && (_MSC_VER >= 1900) // 1900 means VC 14.0,2015, there some problem with std::atomic implement in old MSVC #include #define __UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD @@ -51,9 +81,8 @@ #include -#include -#include - +#include "config/compile_optimize.h" +#include "config/compiler_features.h" namespace util { namespace lock { @@ -88,15 +117,16 @@ namespace util { atomic_int_type &operator=(const atomic_int_type &) volatile UTIL_CONFIG_DELETED_FUNCTION; #endif + public: atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() {} atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT : data_(desired) {} - inline void store(value_type desired, + inline void store(value_type desired, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { data_.store(desired, order); } - inline void store(value_type desired, + inline void store(value_type desired, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { data_.store(desired, order); } @@ -112,24 +142,30 @@ namespace util { inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); } inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); } - inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { store(desired); } - inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { store(desired); } + inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } + inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } inline value_type operator++() UTIL_CONFIG_NOEXCEPT { return ++data_; } inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT { return ++data_; } - inline value_type operator++(int)UTIL_CONFIG_NOEXCEPT { return data_++; } - inline value_type operator++(int)volatile UTIL_CONFIG_NOEXCEPT { return data_++; } + inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT { return data_++; } + inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT { return data_++; } inline value_type operator--() UTIL_CONFIG_NOEXCEPT { return --data_; } inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT { return --data_; } - inline value_type operator--(int)UTIL_CONFIG_NOEXCEPT { return data_--; } - inline value_type operator--(int)volatile UTIL_CONFIG_NOEXCEPT { return data_--; } + inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT { return data_--; } + inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT { return data_--; } - inline value_type exchange(value_type desired, + inline value_type exchange(value_type desired, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.exchange(desired, order); } inline value_type - exchange(value_type desired, + exchange(value_type desired, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { return data_.exchange(desired, order); } @@ -173,7 +209,7 @@ namespace util { return data_.compare_exchange_strong(expected, desired, order); } - inline value_type fetch_add(value_type arg, + inline value_type fetch_add(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.fetch_add(arg, order); } @@ -182,7 +218,7 @@ namespace util { return data_.fetch_add(arg, order); } - inline value_type fetch_sub(value_type arg, + inline value_type fetch_sub(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.fetch_sub(arg, order); } @@ -191,7 +227,7 @@ namespace util { return data_.fetch_sub(arg, order); } - inline value_type fetch_and(value_type arg, + inline value_type fetch_and(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.fetch_and(arg, order); } @@ -200,7 +236,7 @@ namespace util { return data_.fetch_and(arg, order); } - inline value_type fetch_or(value_type arg, + inline value_type fetch_or(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.fetch_or(arg, order); } @@ -209,7 +245,7 @@ namespace util { return data_.fetch_or(arg, order); } - inline value_type fetch_xor(value_type arg, + inline value_type fetch_xor(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { return data_.fetch_xor(arg, order); } @@ -303,10 +339,7 @@ namespace util { private: #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC // char has no cas api in msvc - union { - volatile value_type data_; - volatile short padding; - }; + volatile typename detail::atomic_msvc_oprs::opr_t data_; #else volatile value_type data_; #endif @@ -317,15 +350,28 @@ namespace util { #endif public: - atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() {} + atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() { +#ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC +#if __cplusplus >= 201703L + if + constexpr(sizeof(data_) != sizeof(value_type)) { +#else + if (sizeof(data_) != sizeof(value_type)) { +#endif + data_ = static_cast(data_); + } +#endif + } + atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT : data_(desired) {} - inline void store(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline void + store(value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - int_opr_t::exchange(reinterpret_cast(&data_), static_cast(desired), order); + typedef typename int_opr_t::opr_t opr_t; + int_opr_t::exchange(&data_, static_cast(desired), order); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) __atomic_store_n(&data_, desired, order); @@ -334,12 +380,12 @@ namespace util { #endif } - inline void store(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - int_opr_t::exchange(static_cast(&data_), static_cast(desired), order); + typedef typename int_opr_t::opr_t opr_t; + int_opr_t::exchange(&data_, static_cast(desired), order); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) __atomic_store_n(&data_, desired, order); @@ -348,11 +394,12 @@ namespace util { #endif } - inline value_type load(::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT { + inline value_type + load(EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t:: or (const_cast(reinterpret_cast(&data_)), static_cast(0), order); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: or (const_cast(&data_), static_cast(0), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_load_n(&data_, order); @@ -362,12 +409,12 @@ namespace util { #endif } - inline value_type load(::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const + inline value_type load(EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t:: or (const_cast(reinterpret_cast(&data_)), static_cast(0), order); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: or (const_cast(&data_), static_cast(0), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_load_n(&data_, order); @@ -380,14 +427,20 @@ namespace util { inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); } inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); } - inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { store(desired); } - inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { store(desired); } + inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } + inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } inline value_type operator++() UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::inc(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::inc(&data_, ::util::lock::memory_order_seq_cst)); #else return fetch_add(1) + 1; #endif @@ -395,26 +448,26 @@ namespace util { inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::inc(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::inc(&data_, ::util::lock::memory_order_seq_cst)); #else return fetch_add(1) + 1; #endif } - inline value_type operator++(int)UTIL_CONFIG_NOEXCEPT { + inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::inc(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst) - 1; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::inc(&data_, ::util::lock::memory_order_seq_cst) - 1); #else return fetch_add(1); #endif } - inline value_type operator++(int)volatile UTIL_CONFIG_NOEXCEPT { + inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::inc(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst) - 1; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::inc(&data_, ::util::lock::memory_order_seq_cst) - 1); #else return fetch_add(1); #endif @@ -422,8 +475,8 @@ namespace util { inline value_type operator--() UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::dec(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::dec(&data_, ::util::lock::memory_order_seq_cst)); #else return fetch_sub(1) - 1; #endif @@ -431,38 +484,38 @@ namespace util { inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::dec(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::dec(&data_, ::util::lock::memory_order_seq_cst)); #else return fetch_sub(1) - 1; #endif } - inline value_type operator--(int)UTIL_CONFIG_NOEXCEPT { + inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::dec(reinterpret_cast(&data_), ::util::lock::memory_order_seq_cst) + 1; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::dec(&data_, ::util::lock::memory_order_seq_cst) + 1); #else return fetch_sub(1); #endif } - inline value_type operator--(int)volatile UTIL_CONFIG_NOEXCEPT { + inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return int_opr_t::dec(static_cast(&data_), ::util::lock::memory_order_seq_cst) + 1; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::dec(&data_, ::util::lock::memory_order_seq_cst) + 1); #else return fetch_sub(1); #endif } - inline value_type exchange(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + exchange(value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast( - int_opr_t::exchange(reinterpret_cast(&data_), static_cast(desired), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(static_cast(int_opr_t::exchange(&data_, static_cast(desired), order))); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_exchange_n(&data_, desired, order); @@ -475,13 +528,12 @@ namespace util { #endif } - inline value_type - exchange(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::exchange(static_cast(&data_), static_cast(desired), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(static_cast(int_opr_t::exchange(&data_, static_cast(desired), order))); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_exchange_n(&data_, desired, order); @@ -494,16 +546,17 @@ namespace util { #endif } - inline bool compare_exchange_weak(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), success))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), success))) { return true; } else { - expected = data_; + expected = static_cast(data_); return false; } @@ -519,16 +572,17 @@ namespace util { #endif } - inline bool compare_exchange_weak(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), success))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), success))) { return true; } else { - expected = data_; + expected = static_cast(data_); return false; } @@ -545,15 +599,16 @@ namespace util { } inline bool compare_exchange_weak(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) + UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(reinterpret_cast(&data_), - static_cast(desired), static_cast(expected), order))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), order))) { return true; } else { - expected = data_; + expected = static_cast(data_); return false; } @@ -569,14 +624,14 @@ namespace util { #endif } - inline bool - compare_exchange_weak(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak( + value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), order))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), order))) { return true; } else { expected = data_; @@ -595,13 +650,14 @@ namespace util { #endif } - inline bool compare_exchange_strong(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), success))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), success))) { return true; } else { expected = data_; @@ -620,13 +676,14 @@ namespace util { #endif } - inline bool compare_exchange_strong(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), success))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), success))) { return true; } else { expected = data_; @@ -645,17 +702,17 @@ namespace util { #endif } - inline bool - compare_exchange_strong(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) + UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(reinterpret_cast(&data_), - static_cast(desired), static_cast(expected), order))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), order))) { return true; } else { - expected = data_; + expected = static_cast(data_); return false; } @@ -671,17 +728,17 @@ namespace util { #endif } - inline bool - compare_exchange_strong(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong( + value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - if (expected == static_cast(int_opr_t::cas(static_cast(&data_), static_cast(desired), - static_cast(expected), order))) { + typedef typename int_opr_t::opr_t opr_t; + if (expected == + static_cast(int_opr_t::cas(&data_, static_cast(desired), static_cast(expected), order))) { return true; } else { - expected = data_; + expected = static_cast(data_); return false; } @@ -697,13 +754,13 @@ namespace util { #endif } - inline value_type fetch_add(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_add(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::add(reinterpret_cast(&data_), static_cast(arg), order)) - - arg; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::add(&data_, static_cast(arg), order)) - arg; #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_add(&data_, arg, order); @@ -711,12 +768,12 @@ namespace util { return __sync_fetch_and_add(&data_, arg); #endif } - inline value_type - fetch_add(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::add(static_cast(&data_), static_cast(arg), order)) - arg; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::add(&data_, static_cast(arg), order)) - arg; #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_add(&data_, arg, order); @@ -725,13 +782,13 @@ namespace util { #endif } - inline value_type fetch_sub(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_sub(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::sub(reinterpret_cast(&data_), static_cast(arg), order)) + - arg; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::sub(&data_, static_cast(arg), order)) + arg; #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_sub(&data_, arg, order); @@ -739,12 +796,12 @@ namespace util { return __sync_fetch_and_sub(&data_, arg); #endif } - inline value_type - fetch_sub(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::sub(static_cast(&data_), static_cast(arg), order)) + arg; + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::sub(&data_, static_cast(arg), order)) + arg; #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_sub(&data_, arg, order); @@ -753,12 +810,13 @@ namespace util { #endif } - inline value_type fetch_and(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_and(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::and(reinterpret_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::and(&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_and(&data_, arg, order); @@ -766,12 +824,12 @@ namespace util { return __sync_fetch_and_and(&data_, arg); #endif } - inline value_type - fetch_and(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t::and(static_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t::and(&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_and(&data_, arg, order); @@ -780,12 +838,13 @@ namespace util { #endif } - inline value_type fetch_or(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_or(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t:: or (reinterpret_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: or (&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_or(&data_, arg, order); @@ -793,12 +852,12 @@ namespace util { return __sync_fetch_and_or(&data_, arg); #endif } - inline value_type - fetch_or(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t:: or (static_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: or (&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_or(&data_, arg, order); @@ -807,13 +866,13 @@ namespace util { #endif } - inline value_type fetch_xor(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_xor(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t:: xor - (reinterpret_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: xor (&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_xor(&data_, arg, order); @@ -821,12 +880,12 @@ namespace util { return __sync_fetch_and_xor(&data_, arg); #endif } - inline value_type - fetch_xor(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { #ifdef __UTIL_LOCK_ATOMIC_INT_ATOMIC_MSVC typedef detail::atomic_msvc_oprs int_opr_t; - typedef typename int_opr_t::opr_t opr_t; - return static_cast(int_opr_t:: xor (static_cast(&data_), static_cast(arg), order)); + typedef typename int_opr_t::opr_t opr_t; + return static_cast(int_opr_t:: xor (&data_, static_cast(arg), order)); #elif defined(__UTIL_LOCK_ATOMIC_INT_ATOMIC_GCC_ATOMIC) return __atomic_fetch_xor(&data_, arg, order); @@ -858,22 +917,24 @@ namespace util { #endif public: - atomic_int_type() UTIL_CONFIG_NOEXCEPT : data_() {} - atomic_int_type(value_type desired) UTIL_CONFIG_NOEXCEPT : data_(desired) {} + atomic_int_type() : data_() {} + atomic_int_type(value_type desired) : data_(desired) {} - inline void store(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline void + store(value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { data_ = desired; } - inline void store(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline void store(value_type desired, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { data_ = desired; } - inline value_type load(::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT { + inline value_type + load(EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT { return data_; } - inline value_type load(::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const + inline value_type load(EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) const volatile UTIL_CONFIG_NOEXCEPT { return data_; } @@ -881,29 +942,35 @@ namespace util { inline operator value_type() const UTIL_CONFIG_NOEXCEPT { return load(); } inline operator value_type() const volatile UTIL_CONFIG_NOEXCEPT { return load(); } - inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { store(desired); } - inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { store(desired); } + inline value_type operator=(value_type desired) UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } + inline value_type operator=(value_type desired) volatile UTIL_CONFIG_NOEXCEPT { + store(desired); + return desired; + } inline value_type operator++() UTIL_CONFIG_NOEXCEPT { return ++data_; } inline value_type operator++() volatile UTIL_CONFIG_NOEXCEPT { return ++data_; } - inline value_type operator++(int)UTIL_CONFIG_NOEXCEPT { return data_++; } - inline value_type operator++(int)volatile UTIL_CONFIG_NOEXCEPT { return data_++; } + inline value_type operator++(int) UTIL_CONFIG_NOEXCEPT { return data_++; } + inline value_type operator++(int) volatile UTIL_CONFIG_NOEXCEPT { return data_++; } inline value_type operator--() UTIL_CONFIG_NOEXCEPT { return --data_; } inline value_type operator--() volatile UTIL_CONFIG_NOEXCEPT { return --data_; } - inline value_type operator--(int)UTIL_CONFIG_NOEXCEPT { return data_--; } - inline value_type operator--(int)volatile UTIL_CONFIG_NOEXCEPT { return data_--; } + inline value_type operator--(int) UTIL_CONFIG_NOEXCEPT { return data_--; } + inline value_type operator--(int) volatile UTIL_CONFIG_NOEXCEPT { return data_--; } - inline value_type exchange(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + exchange(value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; - data_ = desired; + data_ = desired; return ret; } - inline value_type - exchange(value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type exchange(value_type desired, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; - data_ = desired; + data_ = desired; return ret; } @@ -919,111 +986,121 @@ namespace util { } public: - inline bool compare_exchange_weak(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool compare_exchange_weak(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } inline bool compare_exchange_weak(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) + UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool - compare_exchange_weak(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_weak( + value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool compare_exchange_strong(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool compare_exchange_strong(value_type &expected, value_type desired, ::util::lock::memory_order success, - ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order success, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order failure) volatile UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool - compare_exchange_strong(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong(value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) + UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline bool - compare_exchange_strong(value_type &expected, value_type desired, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline bool compare_exchange_strong( + value_type &expected, value_type desired, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { return cas(expected, desired); } - inline value_type fetch_add(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_add(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ += arg; return ret; } - inline value_type - fetch_add(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_add(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ += arg; return ret; } - inline value_type fetch_sub(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_sub(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ -= arg; return ret; } - inline value_type - fetch_sub(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_sub(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ -= arg; return ret; } - inline value_type fetch_and(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_and(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ &= arg; return ret; } - inline value_type - fetch_and(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_and(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ &= arg; return ret; } - inline value_type fetch_or(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_or(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ |= arg; return ret; } - inline value_type - fetch_or(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_or(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ |= arg; return ret; } - inline value_type fetch_xor(value_type arg, - ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { + inline value_type + fetch_xor(value_type arg, + EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ ^= arg; return ret; } - inline value_type - fetch_xor(value_type arg, ::util::lock::memory_order order = ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { + inline value_type fetch_xor(value_type arg, EXPLICIT_UNUSED_ATTR ::util::lock::memory_order order = + ::util::lock::memory_order_seq_cst) volatile UTIL_CONFIG_NOEXCEPT { value_type ret = data_; data_ ^= arg; return ret; } }; - } + } // namespace lock } // namespace util #endif /* _UTIL_LOCK_ATOMIC_INT_TYPE_H_ */ diff --git a/include/libcopp/utils/atomic_int_type_msvc_impl.h b/include/libcopp/utils/atomic_int_type_msvc_impl.h index be5d66a..1faaad6 100755 --- a/include/libcopp/utils/atomic_int_type_msvc_impl.h +++ b/include/libcopp/utils/atomic_int_type_msvc_impl.h @@ -20,6 +20,8 @@ #include +#include + namespace util { namespace lock { @@ -34,43 +36,35 @@ namespace util { namespace detail { - template + template struct atomic_msvc_oprs; - template<> + template <> struct atomic_msvc_oprs<1> { - typedef char opr_t; + typedef SHORT opr_t; - static opr_t exchange(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - return InterlockedExchange8(target, value); + static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + return InterlockedExchange16(target, value); } - static opr_t cas(volatile opr_t * target, opr_t value, opr_t expected, ::util::lock::memory_order order) { - volatile short* star = reinterpret_cast(target); - short real_expect = expected; - real_expect |= 0xFF00 & *star; - + static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) { switch (order) { case ::util::lock::memory_order_relaxed: - return static_cast(InterlockedCompareExchangeNoFence16(star, value, real_expect)); + return static_cast(InterlockedCompareExchangeNoFence16(target, value, expected)); case ::util::lock::memory_order_acquire: - return static_cast(InterlockedCompareExchangeAcquire16(star, value, real_expect)); + return static_cast(InterlockedCompareExchangeAcquire16(target, value, expected)); case ::util::lock::memory_order_release: - return static_cast(InterlockedCompareExchangeRelease16(star, value, real_expect)); + return static_cast(InterlockedCompareExchangeRelease16(target, value, expected)); default: - return static_cast(InterlockedCompareExchange16(star, value, real_expect)); + return static_cast(InterlockedCompareExchange16(target, value, expected)); } } - static opr_t inc(volatile opr_t * target, ::util::lock::memory_order order) { - return add(target, 1, order); - } + static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { return add(target, 1, order); } - static opr_t dec(volatile opr_t * target, ::util::lock::memory_order order) { - return sub(target, 1, order); - } + static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { return sub(target, 1, order); } - static opr_t add(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { // no api just like InterlockedAdd16, use cas to simulate it if (NULL == target || 0 == value) { return 0; @@ -88,7 +82,7 @@ namespace util { return ret; } - static opr_t sub(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { // no api just like InterlockedAdd16, use cas to simulate it if (NULL == target || 0 == value) { return 0; @@ -106,67 +100,66 @@ namespace util { return ret; } - static opr_t and(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - return InterlockedAnd8(target, value); + static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + return InterlockedAnd16(target, value); } - static opr_t or(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - return InterlockedOr8(target, value); + static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + return InterlockedOr16(target, value); } - static opr_t xor(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - return InterlockedXor8(target, value); - } + static opr_t xor + (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedXor16(target, value); } }; - template<> + template <> struct atomic_msvc_oprs<2> { typedef SHORT opr_t; - static opr_t exchange(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { return InterlockedExchange16(target, value); } - static opr_t cas(volatile opr_t * target, opr_t value, opr_t expected, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedCompareExchangeNoFence16(target, value, expected); - case ::util::lock::memory_order_acquire: - return InterlockedCompareExchangeAcquire16(target, value, expected); - case ::util::lock::memory_order_release: - return InterlockedCompareExchangeRelease16(target, value, expected); - default: - return InterlockedCompareExchange16(target, value, expected); + static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedCompareExchangeNoFence16(target, value, expected); + case ::util::lock::memory_order_acquire: + return InterlockedCompareExchangeAcquire16(target, value, expected); + case ::util::lock::memory_order_release: + return InterlockedCompareExchangeRelease16(target, value, expected); + default: + return InterlockedCompareExchange16(target, value, expected); } } - static opr_t inc(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedIncrementNoFence16(target); - case ::util::lock::memory_order_acquire: - return InterlockedIncrementAcquire16(target); - case ::util::lock::memory_order_release: - return InterlockedIncrementRelease16(target); - default: - return InterlockedIncrement16(target); + static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedIncrementNoFence16(target); + case ::util::lock::memory_order_acquire: + return InterlockedIncrementAcquire16(target); + case ::util::lock::memory_order_release: + return InterlockedIncrementRelease16(target); + default: + return InterlockedIncrement16(target); } } - static opr_t dec(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedDecrementNoFence16(target); - case ::util::lock::memory_order_acquire: - return InterlockedDecrementAcquire16(target); - case ::util::lock::memory_order_release: - return InterlockedDecrementRelease16(target); - default: - return InterlockedDecrement16(target); + static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedDecrementNoFence16(target); + case ::util::lock::memory_order_acquire: + return InterlockedDecrementAcquire16(target); + case ::util::lock::memory_order_release: + return InterlockedDecrementRelease16(target); + default: + return InterlockedDecrement16(target); } } - static opr_t add(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { // no api just like InterlockedAdd16, use cas to simulate it if (NULL == target || 0 == value) { return 0; @@ -184,7 +177,7 @@ namespace util { return ret; } - static opr_t sub(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { // no api just like InterlockedAdd16, use cas to simulate it if (NULL == target || 0 == value) { return 0; @@ -202,260 +195,333 @@ namespace util { return ret; } - static opr_t and(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedAnd16(target, value); } - static opr_t or(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedOr16(target, value); } - static opr_t xor(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - return InterlockedXor16(target, value); + static opr_t xor + (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedXor16(target, value); } + }; + + template <> + struct atomic_msvc_oprs<4> { + typedef LONG opr_t; + + static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + return InterlockedExchange(target, value); + } + + static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return static_cast(InterlockedCompareExchangeNoFence(target, value, expected)); + case ::util::lock::memory_order_acquire: + return static_cast(InterlockedCompareExchangeAcquire(target, value, expected)); + case ::util::lock::memory_order_release: + return static_cast(InterlockedCompareExchangeRelease(target, value, expected)); + default: + return static_cast(InterlockedCompareExchange(target, value, expected)); + } + } + + static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { return add(target, 1, order); } + + static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { return sub(target, 1, order); } + + static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + // no api just like InterlockedAdd16, use cas to simulate it + if (NULL == target || 0 == value) { + return 0; + } + + opr_t ret = *target; + while (true) { + if (ret == cas(target, ret + value, ret, order)) { + ret += value; + break; + } + ret = *target; + } + + return ret; + } + + static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + // no api just like InterlockedAdd16, use cas to simulate it + if (NULL == target || 0 == value) { + return 0; + } + + opr_t ret = *target; + while (true) { + if (ret == cas(target, ret - value, ret, order)) { + ret -= value; + break; + } + ret = *target; + } + + return ret; + } + + static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + return InterlockedAnd(target, value); + } + + static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + return InterlockedOr(target, value); + } + + static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + return InterlockedXor(target, value); } }; - template<> + template <> struct atomic_msvc_oprs<8> { typedef LONGLONG opr_t; - static opr_t exchange(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedExchangeNoFence64(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedExchangeAcquire64(target, value); - default: - return InterlockedExchange64(target, value); - } - } - - static opr_t cas(volatile opr_t * target, opr_t value, opr_t expected, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedCompareExchangeNoFence64(target, value, expected); - case ::util::lock::memory_order_acquire: - return InterlockedCompareExchangeAcquire64(target, value, expected); - case ::util::lock::memory_order_release: - return InterlockedCompareExchangeRelease64(target, value, expected); - default: - return InterlockedCompareExchange64(target, value, expected); - } - } - - static opr_t inc(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedIncrementNoFence64(target); - case ::util::lock::memory_order_acquire: - return InterlockedIncrementAcquire64(target); - case ::util::lock::memory_order_release: - return InterlockedIncrementRelease64(target); - default: - return InterlockedIncrement64(target); - } - } - - static opr_t dec(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedDecrementNoFence64(target); - case ::util::lock::memory_order_acquire: - return InterlockedDecrementAcquire64(target); - case ::util::lock::memory_order_release: - return InterlockedDecrementRelease64(target); - default: - return InterlockedDecrement64(target); - } - } - - static opr_t add(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAddNoFence64(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedAddAcquire64(target, value); - case ::util::lock::memory_order_release: - return InterlockedAddRelease64(target, value); - default: - return InterlockedAdd64(target, value); - } - } - - static opr_t sub(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAddNoFence64(target, ~(value - 1)); - case ::util::lock::memory_order_acquire: - return InterlockedAddAcquire64(target, ~(value - 1)); - case ::util::lock::memory_order_release: - return InterlockedAddRelease64(target, ~(value - 1)); - default: - return InterlockedAdd64(target, ~(value - 1)); - } - } - - static opr_t and(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAnd64NoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedAnd64Acquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedAnd64Release(target, value); - default: - return InterlockedAnd64(target, value); - } - } - - static opr_t or(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedOr64NoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedOr64Acquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedOr64Release(target, value); - default: - return InterlockedOr64(target, value); - } - } - - static opr_t xor(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedXor64NoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedXor64Acquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedXor64Release(target, value); - default: - return InterlockedXor64(target, value); + static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedExchangeNoFence64(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedExchangeAcquire64(target, value); + default: + return InterlockedExchange64(target, value); + } + } + + static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedCompareExchangeNoFence64(target, value, expected); + case ::util::lock::memory_order_acquire: + return InterlockedCompareExchangeAcquire64(target, value, expected); + case ::util::lock::memory_order_release: + return InterlockedCompareExchangeRelease64(target, value, expected); + default: + return InterlockedCompareExchange64(target, value, expected); + } + } + + static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedIncrementNoFence64(target); + case ::util::lock::memory_order_acquire: + return InterlockedIncrementAcquire64(target); + case ::util::lock::memory_order_release: + return InterlockedIncrementRelease64(target); + default: + return InterlockedIncrement64(target); + } + } + + static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedDecrementNoFence64(target); + case ::util::lock::memory_order_acquire: + return InterlockedDecrementAcquire64(target); + case ::util::lock::memory_order_release: + return InterlockedDecrementRelease64(target); + default: + return InterlockedDecrement64(target); + } + } + + static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAddNoFence64(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedAddAcquire64(target, value); + case ::util::lock::memory_order_release: + return InterlockedAddRelease64(target, value); + default: + return InterlockedAdd64(target, value); + } + } + + static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAddNoFence64(target, ~(value - 1)); + case ::util::lock::memory_order_acquire: + return InterlockedAddAcquire64(target, ~(value - 1)); + case ::util::lock::memory_order_release: + return InterlockedAddRelease64(target, ~(value - 1)); + default: + return InterlockedAdd64(target, ~(value - 1)); + } + } + + static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAnd64NoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedAnd64Acquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedAnd64Release(target, value); + default: + return InterlockedAnd64(target, value); + } + } + + static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedOr64NoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedOr64Acquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedOr64Release(target, value); + default: + return InterlockedOr64(target, value); + } + } + + static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedXor64NoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedXor64Acquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedXor64Release(target, value); + default: + return InterlockedXor64(target, value); } } }; - template + template struct atomic_msvc_oprs { - typedef LONG opr_t; + typedef LONGLONG opr_t; + + static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedExchangeNoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedExchangeAcquire(target, value); + default: + return InterlockedExchange(target, value); + } + } + + static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedCompareExchangeNoFence(target, value, expected); + case ::util::lock::memory_order_acquire: + return InterlockedCompareExchangeAcquire(target, value, expected); + case ::util::lock::memory_order_release: + return InterlockedCompareExchangeRelease(target, value, expected); + default: + return InterlockedCompareExchange(target, value, expected); + } + } + + static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedIncrementNoFence(target); + case ::util::lock::memory_order_acquire: + return InterlockedIncrementAcquire(target); + case ::util::lock::memory_order_release: + return InterlockedIncrementRelease(target); + default: + return InterlockedIncrement(target); + } + } + + static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedDecrementNoFence(target); + case ::util::lock::memory_order_acquire: + return InterlockedDecrementAcquire(target); + case ::util::lock::memory_order_release: + return InterlockedDecrementRelease(target); + default: + return InterlockedDecrement(target); + } + } + + static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAddNoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedAddAcquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedAddRelease(target, value); + default: + return InterlockedAdd(target, value); + } + } + + static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAddNoFence(target, ~(value - 1)); + case ::util::lock::memory_order_acquire: + return InterlockedAddAcquire(target, ~(value - 1)); + case ::util::lock::memory_order_release: + return InterlockedAddRelease(target, ~(value - 1)); + default: + return InterlockedAdd(target, ~(value - 1)); + } + } + + static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedAndNoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedAndAcquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedAndRelease(target, value); + default: + return InterlockedAnd(target, value); + } + } - static opr_t exchange(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedExchangeNoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedExchangeAcquire(target, value); - default: - return InterlockedExchange(target, value); - } - } - - static opr_t cas(volatile opr_t * target, opr_t value, opr_t expected, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedCompareExchangeNoFence(target, value, expected); - case ::util::lock::memory_order_acquire: - return InterlockedCompareExchangeAcquire(target, value, expected); - case ::util::lock::memory_order_release: - return InterlockedCompareExchangeRelease(target, value, expected); - default: - return InterlockedCompareExchange(target, value, expected); - } - } - - static opr_t inc(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedIncrementNoFence(target); - case ::util::lock::memory_order_acquire: - return InterlockedIncrementAcquire(target); - case ::util::lock::memory_order_release: - return InterlockedIncrementRelease(target); - default: - return InterlockedIncrement(target); - } - } - - static opr_t dec(volatile opr_t * target, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedDecrementNoFence(target); - case ::util::lock::memory_order_acquire: - return InterlockedDecrementAcquire(target); - case ::util::lock::memory_order_release: - return InterlockedDecrementRelease(target); - default: - return InterlockedDecrement(target); - } - } - - static opr_t add(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAddNoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedAddAcquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedAddRelease(target, value); - default: - return InterlockedAdd(target, value); - } - } - - static opr_t sub(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAddNoFence(target, ~(value - 1)); - case ::util::lock::memory_order_acquire: - return InterlockedAddAcquire(target, ~(value - 1)); - case ::util::lock::memory_order_release: - return InterlockedAddRelease(target, ~(value - 1)); - default: - return InterlockedAdd(target, ~(value - 1)); - } - } - - static opr_t and(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedAndNoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedAndAcquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedAndRelease(target, value); - default: - return InterlockedAnd(target, value); - } - } - - static opr_t or(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedOrNoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedOrAcquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedOrRelease(target, value); - default: - return InterlockedOr(target, value); - } - } - - static opr_t xor(volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { - switch(order) { - case ::util::lock::memory_order_relaxed: - return InterlockedXorNoFence(target, value); - case ::util::lock::memory_order_acquire: - return InterlockedXorAcquire(target, value); - case ::util::lock::memory_order_release: - return InterlockedXorRelease(target, value); - default: - return InterlockedXor(target, value); + static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedOrNoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedOrAcquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedOrRelease(target, value); + default: + return InterlockedOr(target, value); + } + } + + static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { + switch (order) { + case ::util::lock::memory_order_relaxed: + return InterlockedXorNoFence(target, value); + case ::util::lock::memory_order_acquire: + return InterlockedXorAcquire(target, value); + case ::util::lock::memory_order_release: + return InterlockedXorRelease(target, value); + default: + return InterlockedXor(target, value); } } }; - } - } -} + } // namespace detail + } // namespace lock +} // namespace util #endif /* _UTIL_LOCK_ATOMIC_INT_TYPE_MSVC_IMPL_H_ */ diff --git a/include/libcopp/utils/config/compile_optimize.h b/include/libcopp/utils/config/compile_optimize.h new file mode 100644 index 0000000..d703c49 --- /dev/null +++ b/include/libcopp/utils/config/compile_optimize.h @@ -0,0 +1,142 @@ +#ifndef UTIL_CONFIG_COMPILE_OPTIMIZE_H +#define UTIL_CONFIG_COMPILE_OPTIMIZE_H + +#pragma once + + +// ================ branch prediction information ================ +#ifndef likely +#ifdef __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#else +#define likely(x) !!(x) +#endif +#endif + +#ifndef unlikely +#ifdef __GNUC__ +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define unlikely(x) !!(x) +#endif +#endif + +#ifndef unreachable +#ifdef __GNUC__ +#ifdef __clang__ +#if __has_builtin(__builtin_unreachable) +#define unreachable() __builtin_unreachable() +#else +#define unreachable() abort() +#endif +#else +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define unreachable() __builtin_unreachable() +#else +#define unreachable() abort() +#endif +#endif +#else +#define unreachable() abort() +#endif +#endif +// ---------------- branch prediction information ---------------- + +// ================ import/export ================ +// 不支持 borland/sunpro_cc/xlcpp + +// ================ import/export: for compilers ================ +#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#define UTIL_SYMBOL_EXPORT __attribute__((visibility("default"))) +#define UTIL_SYMBOL_IMPORT +#define UTIL_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#endif + +#elif defined __clang__ && !defined(__CUDACC__) && !defined(__ibmxl__) +// when using clang and cuda at same time, you want to appear as gcc +// Clang C++ emulates GCC, so it has to appear early. +// + +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +#define UTIL_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +#define UTIL_SYMBOL_IMPORT +#define UTIL_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#endif + +#elif defined(__GNUC__) && !defined(__ibmxl__) +// GNU C++: +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__) +// All Win32 development environments, including 64-bit Windows and MinGW, define +// _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, +// so does not define _WIN32 or its variants. +#define BOOST_HAS_DECLSPEC +#define UTIL_SYMBOL_EXPORT __attribute__((__dllexport__)) +#define UTIL_SYMBOL_IMPORT __attribute__((__dllimport__)) +#else +#define UTIL_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +#define UTIL_SYMBOL_IMPORT +#endif +#define UTIL_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#else +// config/platform/win32.hpp will define UTIL_SYMBOL_EXPORT, etc., unless already defined +#define UTIL_SYMBOL_EXPORT +#endif + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +#else +#endif +// ---------------- import/export: for compilers ---------------- + +// ================ import/export: for platform ================ +// Default defines for UTIL_SYMBOL_EXPORT and UTIL_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define UTIL_SYMBOL_EXPORT and +// UTIL_SYMBOL_IMPORT +#ifndef UTIL_SYMBOL_EXPORT +#define UTIL_SYMBOL_EXPORT __declspec(dllexport) +#define UTIL_SYMBOL_IMPORT __declspec(dllimport) +#endif +// ---------------- import/export: for platform ---------------- + +#ifndef UTIL_SYMBOL_EXPORT +#define UTIL_SYMBOL_EXPORT +#endif +#ifndef UTIL_SYMBOL_IMPORT +#define UTIL_SYMBOL_IMPORT +#endif +#ifndef UTIL_SYMBOL_VISIBLE +#define UTIL_SYMBOL_VISIBLE +#endif + +// ---------------- import/export ---------------- + +// ================ __cdecl ================ +#if defined(__GNUC__) +#ifndef __cdecl +// see https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html +// Intel x86 architecture specific calling conventions +#ifdef _M_IX86 +#define __cdecl __attribute__((__cdecl__)) +#else +#define __cdecl +#endif +#endif +#endif +// ---------------- __cdecl ---------------- + +#endif \ No newline at end of file diff --git a/include/libcopp/utils/lock_holder.h b/include/libcopp/utils/lock_holder.h index f7b04b6..442758a 100755 --- a/include/libcopp/utils/lock_holder.h +++ b/include/libcopp/utils/lock_holder.h @@ -1,79 +1,123 @@ -/** - * @file lock_holder.h - * @brief 锁管理器 - * Licensed under the MIT licenses. - * - * @version 1.0 - * @author owent - * @date 2015-06-29 - * - * @note 实现锁的自管理操作,类似std::lock_guard,增加了针对特定场合使用的try_unlock函数 - * - * @history - */ - +/** + * @file lock_holder.h + * @brief 锁管理器 + * Licensed under the MIT licenses. + * + * @version 1.0 + * @author owent + * @date 2015-06-29 + * + * @note 实现锁的自管理操作,类似std::lock_guard,增加了针对特定场合使用的try_unlock函数 + * + * @history + */ + #ifndef UTIL_LOCK_LOCK_HOLDER_H #define UTIL_LOCK_LOCK_HOLDER_H - -#pragma once - -#include - -namespace util { - namespace lock { - namespace detail { - template - struct default_lock_action { - bool operator()(TLock &lock) const { - lock.lock(); - return true; - } - }; - - template - struct default_try_lock_action { - bool operator()(TLock &lock) const { return lock.try_lock(); } - }; - - template - struct default_unlock_action { - void operator()(TLock &lock) const { lock.unlock(); } - }; - - template - struct default_try_unlock_action { - bool operator()(TLock &lock) const { return lock.try_unlock(); } - }; - } - - template , - typename TUnlockAct = detail::default_unlock_action > - class lock_holder { - public: - typedef TLock value_type; - - lock_holder(TLock &lock) : lock_flag_(&lock) { - if (false == TLockAct()(lock)) { - lock_flag_ = NULL; - } - } - - ~lock_holder() { - if (NULL != lock_flag_) { - TUnlockAct()(*lock_flag_); - } - } - - bool is_available() const { return NULL != lock_flag_; } - - private: - lock_holder(const lock_holder &); - lock_holder &operator=(const lock_holder &); - - private: - value_type *lock_flag_; - }; - } -} - -#endif /* _UTIL_LOCK_LOCK_HOLDER_H_ */ + +#pragma once + +#include + +#include "config/compiler_features.h" + +namespace util { + namespace lock { + namespace detail { + template + struct default_lock_action { + bool operator()(TLock &lock) const { + lock.lock(); + return true; + } + }; + + template + struct default_try_lock_action { + bool operator()(TLock &lock) const { return lock.try_lock(); } + }; + + template + struct default_unlock_action { + void operator()(TLock &lock) const { lock.unlock(); } + }; + + template + struct default_try_unlock_action { + bool operator()(TLock &lock) const { return lock.try_unlock(); } + }; + + template + struct default_read_lock_action { + bool operator()(TLock &lock) const { + lock.read_lock(); + return true; + } + }; + + template + struct default_read_unlock_action { + void operator()(TLock &lock) const { lock.read_unlock(); } + }; + + template + struct default_write_lock_action { + bool operator()(TLock &lock) const { + lock.write_lock(); + return true; + } + }; + + template + struct default_write_unlock_action { + void operator()(TLock &lock) const { lock.write_unlock(); } + }; + } // namespace detail + + template , + typename TUnlockAct = detail::default_unlock_action > + class lock_holder { + public: + typedef TLock value_type; + + lock_holder(TLock &lock) : lock_flag_(&lock) { + if (false == TLockAct()(lock)) { + lock_flag_ = NULL; + } + } + + ~lock_holder() { + if (NULL != lock_flag_) { + TUnlockAct()(*lock_flag_); + } + } + + bool is_available() const { return NULL != lock_flag_; } + + private: + lock_holder(const lock_holder &) UTIL_CONFIG_DELETED_FUNCTION; + lock_holder &operator=(const lock_holder &) UTIL_CONFIG_DELETED_FUNCTION; + + private: + value_type *lock_flag_; + }; + + template + class read_lock_holder + : public lock_holder, detail::default_read_unlock_action > { + public: + read_lock_holder(TLock &lock) + : lock_holder, detail::default_read_unlock_action >(lock) {} + }; + + template + class write_lock_holder + : public lock_holder, detail::default_write_unlock_action > { + public: + write_lock_holder(TLock &lock) + : lock_holder, detail::default_write_unlock_action >(lock) {} + }; + } // namespace lock +} // namespace util + +#endif /* _UTIL_LOCK_LOCK_HOLDER_H_ */ diff --git a/src/libcopp/stack/allocator/stack_allocator_memory.cpp b/src/libcopp/stack/allocator/stack_allocator_memory.cpp index 557ffda..cfbee41 100755 --- a/src/libcopp/stack/allocator/stack_allocator_memory.cpp +++ b/src/libcopp/stack/allocator/stack_allocator_memory.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "libcopp/stack/allocator/stack_allocator_memory.h" #include "libcopp/stack/stack_context.h" #include "libcopp/stack/stack_traits.h" @@ -96,7 +98,7 @@ namespace copp { is_used_ = true; } - void stack_allocator_memory::deallocate(stack_context &ctx) UTIL_CONFIG_NOEXCEPT { + void stack_allocator_memory::deallocate(EXPLICIT_UNUSED_ATTR stack_context &ctx) UTIL_CONFIG_NOEXCEPT { assert(ctx.sp); assert(stack_traits::minimum_size() <= ctx.size); assert(stack_traits::is_unbounded() || (stack_traits::maximum_size() >= ctx.size));