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