#ifndef BOOST_ATOMIC_HPP #define BOOST_ATOMIC_HPP // Copyright (c) 2009 Helge Bahmann // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include //#include namespace boost { template class atomic : public detail::atomic::internal_atomic { public: typedef detail::atomic::internal_atomic super; atomic() {} explicit atomic(T v) : super(v) {} private: atomic(const atomic &); void operator=(const atomic &); }; template<> class atomic : private detail::atomic::internal_atomic { public: typedef detail::atomic::internal_atomic super; atomic() {} explicit atomic(bool v) : super(v) {} using super::load; using super::store; using super::compare_exchange_strong; using super::compare_exchange_weak; using super::exchange; using super::is_lock_free; operator bool(void) const volatile {return load();} bool operator=(bool v) volatile {store(v); return v;} private: atomic(const atomic &); void operator=(const atomic &); }; template<> class atomic : private detail::atomic::internal_atomic { public: typedef detail::atomic::internal_atomic super; atomic() {} explicit atomic(void * p) : super(p) {} using super::load; using super::store; using super::compare_exchange_strong; using super::compare_exchange_weak; using super::exchange; using super::is_lock_free; operator void *(void) const volatile {return load();} void * operator=(void * v) volatile {store(v); return v;} private: atomic(const atomic &); void * operator=(const atomic &); }; /* FIXME: pointer arithmetic still missing */ template class atomic : private detail::atomic::internal_atomic { public: typedef detail::atomic::internal_atomic super; atomic() {} explicit atomic(T * p) : super((intptr_t)p) {} T *load(memory_order order=memory_order_seq_cst) const volatile { return (T*)super::load(order); } void store(T *v, memory_order order=memory_order_seq_cst) volatile { super::store((intptr_t)v, order); } bool compare_exchange_strong( T * &expected, T * desired, memory_order order=memory_order_seq_cst) volatile { return compare_exchange_strong(expected, desired, order, detail::atomic::calculate_failure_order(order)); } bool compare_exchange_weak( T * &expected, T *desired, memory_order order=memory_order_seq_cst) volatile { return compare_exchange_weak(expected, desired, order, detail::atomic::calculate_failure_order(order)); } bool compare_exchange_weak( T * &expected, T *desired, memory_order success_order, memory_order failure_order) volatile { intptr_t expected_=(intptr_t)expected; intptr_t desired_=(intptr_t)desired; bool success=super::compare_exchange_weak(expected_, desired_, success_order, failure_order); expected=(T*)expected_; return success; } bool compare_exchange_strong( T * &expected, T *desired, memory_order success_order, memory_order failure_order) volatile { intptr_t expected_=(intptr_t)expected, desired_=(intptr_t)desired; bool success=super::compare_exchange_strong(expected_, desired_, success_order, failure_order); expected=(T*)expected_; return success; } T *exchange(T * replacement, memory_order order=memory_order_seq_cst) volatile { return (T*)super::exchange((intptr_t)replacement, order); } using super::is_lock_free; operator T *(void) const volatile {return load();} T * operator=(T * v) volatile {store(v); return v;} T * fetch_add(ptrdiff_t diff, memory_order order=memory_order_seq_cst) volatile { return (T*)super::fetch_add(diff*sizeof(T), order); } T * fetch_sub(ptrdiff_t diff, memory_order order=memory_order_seq_cst) volatile { return (T*)super::fetch_sub(diff*sizeof(T), order); } T *operator++(void) volatile {return fetch_add(1)+1;} T *operator++(int) volatile {return fetch_add(1);} T *operator--(void) volatile {return fetch_sub(1)-1;} T *operator--(int) volatile {return fetch_sub(1);} private: atomic(const atomic &); T * operator=(const atomic &); }; class atomic_flag : private atomic { public: typedef atomic super; using super::is_lock_free; atomic_flag(bool initial_state) : super(initial_state?1:0) {} atomic_flag() {} bool test_and_set(memory_order order=memory_order_seq_cst) { return super::exchange(1, order) ? true : false; } void clear(memory_order order=memory_order_seq_cst) { super::store(0, order); } }; typedef atomic atomic_char; typedef atomic atomic_uchar; typedef atomic atomic_schar; typedef atomic atomic_uint8_t; typedef atomic atomic_int8_t; typedef atomic atomic_ushort; typedef atomic atomic_short; typedef atomic atomic_uint16_t; typedef atomic atomic_int16_t; typedef atomic atomic_uint; typedef atomic atomic_int; typedef atomic atomic_uint32_t; typedef atomic atomic_int32_t; typedef atomic atomic_ulong; typedef atomic atomic_long; typedef atomic atomic_uint64_t; typedef atomic atomic_int64_t; #ifdef BOOST_HAS_LONG_LONG typedef atomic atomic_ullong; typedef atomic atomic_llong; #endif #ifdef BOOST_ATOMIC_HAVE_GNU_128BIT_INTEGERS typedef atomic<__uint128_t> atomic_uint128_t; typedef atomic<__int128_t> atomic_int128_t; #endif #if BOOST_MSVC >= 1500 && (defined(_M_IA64) || defined(_M_AMD64)) && defined(BOOST_ATOMIC_HAVE_SSE2) typedef atomic<__m128i> atomic_uint128_t; typedef atomic<__m128i> atomic_int128_t; #endif typedef atomic atomic_address; typedef atomic atomic_bool; static inline void atomic_thread_fence(memory_order order) { detail::atomic::platform_atomic_thread_fence(order); } } #endif