123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #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 <cstddef>
- #include <boost/cstdint.hpp>
- #include <boost/memory_order.hpp>
- #include <boost/atomic/detail/config.hpp>
- #include <boost/atomic/detail/base.hpp>
- #include <boost/atomic/detail/builder.hpp>
- #ifdef BOOST_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 <Windows.h>
- #include <intrin.h>
- #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<volatile long*>(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<int>(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 <sys/atomic.h>
- 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<typename T>
- 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_type *>(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<typename T>
- class platform_atomic_integral<T, 4> :
- public build_atomic_from_exchange<atomic_generic_cas32<T> >
- {
- public:
- typedef build_atomic_from_exchange<atomic_generic_cas32<T> > super;
- explicit platform_atomic_integral(T v) : super(v) {}
- platform_atomic_integral(void) {}
- };
- template<typename T>
- class platform_atomic_integral<T, 1> :
- public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
- {
- public:
- typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
- explicit platform_atomic_integral(T v) : super(v) {}
- platform_atomic_integral(void) {}
- };
- template<typename T>
- class platform_atomic_integral<T, 2> :
- public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
- {
- public:
- typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
- explicit platform_atomic_integral(T v) : super(v) {}
- platform_atomic_integral(void) {}
- };
- #endif
- } } }
- #endif
|