00001 #ifndef BOOST_ATOMIC_ATOMIC_HPP
00002 #define BOOST_ATOMIC_ATOMIC_HPP
00003
00004
00005
00006
00007
00008
00009
00010 #include <cstddef>
00011
00012 #include "atomic/memory_order2.hpp"
00013 #include "atomic/platform.hpp"
00014 #include "atomic/detail/base.hpp"
00015 #include "atomic/detail/integral-casts.hpp"
00016
00017 namespace boost_atomic {
00018
00019 template<typename T>
00020 class atomic : public detail::atomic::internal_atomic<T> {
00021 public:
00022 typedef detail::atomic::internal_atomic<T> super;
00023
00024 atomic() {}
00025 explicit atomic(T v) : super(v) {}
00026 private:
00027 atomic(const atomic &);
00028 void operator=(const atomic &);
00029 };
00030
00031
00032 template<>
00033 class atomic<bool> : private detail::atomic::internal_atomic<bool> {
00034 public:
00035 typedef detail::atomic::internal_atomic<bool> super;
00036
00037 atomic() {}
00038 explicit atomic(bool v) : super(v) {}
00039
00040 using super::load;
00041 using super::store;
00042 using super::compare_exchange_strong;
00043 using super::compare_exchange_weak;
00044 using super::exchange;
00045 using super::is_lock_free;
00046
00047 operator bool(void) const volatile {return load();}
00048 bool operator=(bool v) volatile {store(v); return v;}
00049 private:
00050 atomic(const atomic &);
00051 void operator=(const atomic &);
00052 };
00053
00054 template<>
00055 class atomic<void *> : private detail::atomic::internal_atomic<void *, sizeof(void *), int> {
00056 public:
00057 typedef detail::atomic::internal_atomic<void *, sizeof(void *), int> super;
00058
00059 atomic() {}
00060 explicit atomic(void * p) : super(p) {}
00061 using super::load;
00062 using super::store;
00063 using super::compare_exchange_strong;
00064 using super::compare_exchange_weak;
00065 using super::exchange;
00066 using super::is_lock_free;
00067
00068 operator void *(void) const volatile {return load();}
00069 void * operator=(void * v) volatile {store(v); return v;}
00070
00071 private:
00072 atomic(const atomic &);
00073 void * operator=(const atomic &);
00074 };
00075
00076
00077
00078 template<typename T>
00079 class atomic<T *> : private detail::atomic::internal_atomic<intptr_t> {
00080 public:
00081 typedef detail::atomic::internal_atomic<intptr_t> super;
00082
00083 atomic() {}
00084 explicit atomic(T * p) : super((intptr_t)p) {}
00085
00086 T *load(memory_order2 order=memory_order2_seq_cst) const volatile
00087 {
00088 return (T*)super::load(order);
00089 }
00090 void store(T *v, memory_order2 order=memory_order2_seq_cst) volatile
00091 {
00092 super::store((intptr_t)v, order);
00093 }
00094 bool compare_exchange_strong(
00095 T * &expected,
00096 T * desired,
00097 memory_order2 order=memory_order2_seq_cst) volatile
00098 {
00099 return compare_exchange_strong(expected, desired, order, detail::atomic::calculate_failure_order(order));
00100 }
00101 bool compare_exchange_weak(
00102 T * &expected,
00103 T *desired,
00104 memory_order2 order=memory_order2_seq_cst) volatile
00105 {
00106 return compare_exchange_weak(expected, desired, order, detail::atomic::calculate_failure_order(order));
00107 }
00108 bool compare_exchange_weak(
00109 T * &expected,
00110 T *desired,
00111 memory_order2 success_order,
00112 memory_order2 failure_order) volatile
00113 {
00114 intptr_t expected_=(intptr_t)expected, desired_=(intptr_t)desired;
00115 bool success=super::compare_exchange_weak(expected_, desired_, success_order, failure_order);
00116 expected=(T*)expected_;
00117 return success;
00118 }
00119 bool compare_exchange_strong(
00120 T * &expected,
00121 T *desired,
00122 memory_order2 success_order,
00123 memory_order2 failure_order) volatile
00124 {
00125 intptr_t expected_=(intptr_t)expected, desired_=(intptr_t)desired;
00126 bool success=super::compare_exchange_strong(expected_, desired_, success_order, failure_order);
00127 expected=(T*)expected_;
00128 return success;
00129 }
00130 T *exchange(T * replacement, memory_order2 order=memory_order2_seq_cst) volatile
00131 {
00132 return (T*)super::exchange((intptr_t)replacement, order);
00133 }
00134 using super::is_lock_free;
00135
00136 operator T *(void) const volatile {return load();}
00137 T * operator=(T * v) volatile {store(v); return v;}
00138
00139 T * fetch_add(ptrdiff_t diff, memory_order2 order=memory_order2_seq_cst) volatile
00140 {
00141 return (T*)super::fetch_add(diff*sizeof(T), order);
00142 }
00143 T * fetch_sub(ptrdiff_t diff, memory_order2 order=memory_order2_seq_cst) volatile
00144 {
00145 return (T*)super::fetch_sub(diff*sizeof(T), order);
00146 }
00147
00148 T *operator++(void) volatile {return fetch_add(1)+1;}
00149 T *operator++(int) volatile {return fetch_add(1);}
00150 T *operator--(void) volatile {return fetch_sub(1)-1;}
00151 T *operator--(int) volatile {return fetch_sub(1);}
00152 private:
00153 atomic(const atomic &);
00154 T * operator=(const atomic &);
00155 };
00156
00157 class atomic_flag : private atomic<int> {
00158 public:
00159 typedef atomic<int> super;
00160 using super::is_lock_free;
00161
00162 atomic_flag(bool initial_state) : super(initial_state?1:0) {}
00163 atomic_flag() {}
00164
00165 bool test_and_set(memory_order2 order=memory_order2_seq_cst)
00166 {
00167 return super::exchange(1, order) != 0;
00168 }
00169 void clear(memory_order2 order=memory_order2_seq_cst)
00170 {
00171 super::store(0, order);
00172 }
00173 };
00174
00175 typedef atomic<char> atomic_char;
00176 typedef atomic<unsigned char> atomic_uchar;
00177 typedef atomic<signed char> atomic_schar;
00178 typedef atomic<uint8_t> atomic_uint8_t;
00179 typedef atomic<int8_t> atomic_int8_t;
00180 typedef atomic<unsigned short> atomic_ushort;
00181 typedef atomic<short> atomic_short;
00182 typedef atomic<uint16_t> atomic_uint16_t;
00183 typedef atomic<int16_t> atomic_int16_t;
00184 typedef atomic<unsigned int> atomic_uint;
00185 typedef atomic<int> atomic_int;
00186 typedef atomic<uint32_t> atomic_uint32_t;
00187 typedef atomic<int32_t> atomic_int32_t;
00188 typedef atomic<unsigned long> atomic_ulong;
00189 typedef atomic<long> atomic_long;
00190 typedef atomic<uint64_t> atomic_uint64_t;
00191 typedef atomic<int64_t> atomic_int64_t;
00192 typedef atomic<unsigned long long> atomic_ullong;
00193 typedef atomic<long long> atomic_llong;
00194 typedef atomic<void*> atomic_address;
00195 typedef atomic<bool> atomic_bool;
00196
00197 static inline void atomic_thread_fence(memory_order2 order)
00198 {
00199 detail::atomic::platform_atomic_thread_fence<memory_order2>(order);
00200 }
00201
00202 }
00203
00204 #endif