$search
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