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