#ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_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 #ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #pragma once #endif /* fallback implementation for various compilation targets; this is *not* efficient, particularly because all operations are fully fenced (full memory barriers before and after each operation) */ #if defined(__GNUC__) namespace boost { namespace atomics { namespace detail { inline int32_t fenced_compare_exchange_strong_32(volatile int32_t *ptr, int32_t expected, int32_t desired) { return __sync_val_compare_and_swap_4(ptr, expected, desired); } #define BOOST_ATOMIC_HAVE_CAS32 1 #if defined(__amd64__) || defined(__i686__) inline int64_t fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired) { return __sync_val_compare_and_swap_8(ptr, expected, desired); } #define BOOST_ATOMIC_HAVE_CAS64 1 #endif }}} #elif defined(__ICL) || defined(_MSC_VER) #if defined(_MSC_VER) #include #include #endif namespace boost { namespace atomics { namespace detail { inline int32_t fenced_compare_exchange_strong(int32_t *ptr, int32_t expected, int32_t desired) { return _InterlockedCompareExchange(reinterpret_cast(ptr), desired, expected); } #define BOOST_ATOMIC_HAVE_CAS32 1 #if defined(_WIN64) inline int64_t fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired) { return _InterlockedCompareExchange64(ptr, desired, expected); } #define BOOST_ATOMIC_HAVE_CAS64 1 #endif }}} #elif (defined(__ICC) || defined(__ECC)) namespace boost { namespace atomics { namespace detail { inline int32_t fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired) { return _InterlockedCompareExchange((void*)ptr, desired, expected); } #define BOOST_ATOMIC_HAVE_CAS32 1 #if defined(__x86_64) inline int64_t fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired) { return cas64(ptr, expected, desired); } #define BOOST_ATOMIC_HAVE_CAS64 1 #elif defined(__ECC) //IA-64 version inline int64_t fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired) { return _InterlockedCompareExchange64((void*)ptr, desired, expected); } #define BOOST_ATOMIC_HAVE_CAS64 1 #endif }}} #elif (defined(__SUNPRO_CC) && defined(__sparc)) #include namespace boost { namespace atomics { namespace detail { inline int32_t fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired) { return atomic_cas_32((volatile unsigned int*)ptr, expected, desired); } #define BOOST_ATOMIC_HAVE_CAS32 1 /* FIXME: check for 64 bit mode */ inline int64_t fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired) { return atomic_cas_64((volatile unsigned long long*)ptr, expected, desired); } #define BOOST_ATOMIC_HAVE_CAS64 1 }}} #endif namespace boost { namespace atomics { namespace detail { #ifdef BOOST_ATOMIC_HAVE_CAS32 template class atomic_generic_cas32 { private: typedef atomic_generic_cas32 this_type; public: explicit atomic_generic_cas32(T v) : i((int32_t)v) {} atomic_generic_cas32() {} T load(memory_order order=memory_order_seq_cst) const volatile { T expected=(T)i; do { } while(!const_cast(this)->compare_exchange_weak(expected, expected, order, memory_order_relaxed)); return expected; } void store(T v, memory_order order=memory_order_seq_cst) volatile { exchange(v); } bool compare_exchange_strong( T &expected, T desired, memory_order success_order, memory_order failure_order) volatile { T found; found=(T)fenced_compare_exchange_strong_32(&i, (int32_t)expected, (int32_t)desired); bool success=(found==expected); expected=found; return success; } bool compare_exchange_weak( T &expected, T desired, memory_order success_order, memory_order failure_order) volatile { return compare_exchange_strong(expected, desired, success_order, failure_order); } T exchange(T r, memory_order order=memory_order_seq_cst) volatile { T expected=(T)i; do { } while(!compare_exchange_weak(expected, r, order, memory_order_relaxed)); return expected; } bool is_lock_free(void) const volatile {return true;} typedef T integral_type; private: mutable int32_t i; }; template class platform_atomic_integral : public build_atomic_from_exchange > { public: typedef build_atomic_from_exchange > super; explicit platform_atomic_integral(T v) : super(v) {} platform_atomic_integral(void) {} }; template class platform_atomic_integral: public build_atomic_from_larger_type, T> { public: typedef build_atomic_from_larger_type, T> super; explicit platform_atomic_integral(T v) : super(v) {} platform_atomic_integral(void) {} }; template class platform_atomic_integral: public build_atomic_from_larger_type, T> { public: typedef build_atomic_from_larger_type, T> super; explicit platform_atomic_integral(T v) : super(v) {} platform_atomic_integral(void) {} }; #endif } } } #endif