generic-cas.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_DETAIL_ATOMIC_GENERIC_CAS_HPP
00002 #define BOOST_DETAIL_ATOMIC_GENERIC_CAS_HPP
00003 
00004 //  Copyright (c) 2009 Helge Bahmann
00005 //
00006 //  Distributed under the Boost Software License, Version 1.0.
00007 //  See accompanying file LICENSE_1_0.txt or copy at
00008 //  http://www.boost.org/LICENSE_1_0.txt)
00009 
00010 #include <stdint.h>
00011 
00012 #include <boost/memory_order.hpp>
00013 #include <boost/atomic/detail/base.hpp>
00014 #include <boost/atomic/detail/builder.hpp>
00015 
00016 /* fallback implementation for various compilation targets;
00017 this is *not* efficient, particularly because all operations
00018 are fully fenced (full memory barriers before and after
00019 each operation) */
00020 
00021 #if defined(__GNUC__)
00022         namespace boost { namespace detail { namespace atomic {
00023         static inline int32_t
00024         fenced_compare_exchange_strong_32(volatile int32_t *ptr, int32_t expected, int32_t desired)
00025         {
00026                 return __sync_val_compare_and_swap_4(ptr, expected, desired);
00027         }
00028         #define BOOST_ATOMIC_HAVE_CAS32 1
00029         
00030         #if defined(__amd64__) || defined(__i686__)
00031         static inline int64_t
00032         fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
00033         {
00034                 return __sync_val_compare_and_swap_8(ptr, expected, desired);
00035         }
00036         #define BOOST_ATOMIC_HAVE_CAS64 1
00037         #endif
00038         }}}
00039 
00040 #elif defined(__ICL) || defined(_MSC_VER)
00041 
00042         #if defined(_MSC_VER)
00043         #include <Windows.h>
00044         #include <intrin.h>
00045         #endif
00046 
00047         namespace boost { namespace detail { namespace atomic {
00048         static inline int32_t
00049         fenced_compare_exchange_strong(int32_t *ptr, int32_t expected, int32_t desired)
00050         {
00051                 return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), desired, expected);
00052         }
00053         #define BOOST_ATOMIC_HAVE_CAS32 1
00054         #if defined(_WIN64)
00055         static inline int64_t
00056         fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
00057         {
00058                 return _InterlockedCompareExchange64(ptr, desired, expected);
00059         }
00060         #define BOOST_ATOMIC_HAVE_CAS64 1
00061         #endif
00062         }}}
00063         
00064 #elif (defined(__ICC) || defined(__ECC))
00065         namespace boost { namespace detail { namespace atomic {
00066         static inline int32_t
00067         fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
00068         {
00069                 return _InterlockedCompareExchange((void*)ptr, desired, expected);
00070         }
00071         #define BOOST_ATOMIC_HAVE_CAS32 1
00072         #if defined(__x86_64)
00073         static inline int64_t
00074         fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
00075         {
00076                 return cas64<int>(ptr, expected, desired);
00077         }
00078         #define BOOST_ATOMIC_HAVE_CAS64 1
00079         #elif defined(__ECC)    //IA-64 version
00080         static inline int64_t
00081         fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
00082         {
00083                 return _InterlockedCompareExchange64((void*)ptr, desired, expected);
00084         }
00085         #define BOOST_ATOMIC_HAVE_CAS64 1
00086         #endif
00087         }}}
00088         
00089 #elif (defined(__SUNPRO_CC) && defined(__sparc))
00090         #include <sys/atomic.h>
00091         namespace boost { namespace detail { namespace atomic {
00092         static inline int32_t
00093         fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
00094         {
00095                 return atomic_cas_32((volatile unsigned int*)ptr, expected, desired);
00096         }
00097         #define BOOST_ATOMIC_HAVE_CAS32 1
00098         
00099         /* FIXME: check for 64 bit mode */
00100         static inline int64_t
00101         fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
00102         {
00103                 return atomic_cas_64((volatile unsigned long long*)ptr, expected, desired);
00104         }
00105         #define BOOST_ATOMIC_HAVE_CAS64 1
00106         }}}
00107 #endif
00108 
00109 
00110 namespace boost { namespace detail { namespace atomic {
00111 
00112 #ifdef BOOST_ATOMIC_HAVE_CAS32
00113 template<typename T>
00114 class atomic_generic_cas32 {
00115 private:
00116         typedef atomic_generic_cas32 this_type;
00117 public:
00118         explicit atomic_generic_cas32(T v) : i((int32_t)v) {}
00119         atomic_generic_cas32() {}
00120         T load(memory_order order=memory_order_seq_cst) const volatile
00121         {
00122                 T expected=(T)i;
00123                 do { } while(!const_cast<this_type *>(this)->compare_exchange_weak(expected, expected, order, memory_order_relaxed));
00124                 return expected;
00125         }
00126         void store(T v, memory_order order=memory_order_seq_cst) volatile
00127         {
00128                 exchange(v);
00129         }
00130         bool compare_exchange_strong(
00131                 T &expected,
00132                 T desired,
00133                 memory_order success_order,
00134                 memory_order failure_order) volatile
00135         {
00136                 T found;
00137                 found=(T)fenced_compare_exchange_strong_32(&i, (int32_t)expected, (int32_t)desired);
00138                 bool success=(found==expected);
00139                 expected=found;
00140                 return success;
00141         }
00142         bool compare_exchange_weak(
00143                 T &expected,
00144                 T desired,
00145                 memory_order success_order,
00146                 memory_order failure_order) volatile
00147         {
00148                 return compare_exchange_strong(expected, desired, success_order, failure_order);
00149         }
00150         T exchange(T r, memory_order order=memory_order_seq_cst) volatile
00151         {
00152                 T expected=(T)i;
00153                 do { } while(!compare_exchange_weak(expected, r, order, memory_order_relaxed));
00154                 return expected;
00155         }
00156         
00157         bool is_lock_free(void) const volatile {return true;}
00158         typedef T integral_type;
00159 private:
00160         mutable int32_t i;
00161 };
00162 
00163 template<typename T>
00164 class platform_atomic_integral<T, 4> : public build_atomic_from_exchange<atomic_generic_cas32<T> > {
00165 public:
00166         typedef build_atomic_from_exchange<atomic_generic_cas32<T> > super;
00167         explicit platform_atomic_integral(T v) : super(v) {}
00168         platform_atomic_integral(void) {}
00169 };
00170 
00171 template<typename T>
00172 class platform_atomic_integral<T, 1>: public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> {
00173 public:
00174         typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
00175         
00176         explicit platform_atomic_integral(T v) : super(v) {}
00177         platform_atomic_integral(void) {}
00178 };
00179 
00180 template<typename T>
00181 class platform_atomic_integral<T, 2>: public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> {
00182 public:
00183         typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
00184         
00185         explicit platform_atomic_integral(T v) : super(v) {}
00186         platform_atomic_integral(void) {}
00187 };
00188 #endif
00189 
00190 } } }
00191 
00192 #endif


rosatomic
Author(s): Josh Faust
autogenerated on Wed Aug 26 2015 15:59:58