00001 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_BASE_HPP
00002 #define BOOST_ATOMIC_DETAIL_ATOMIC_BASE_HPP
00003
00004
00005
00006
00007
00008
00009
00010 #include "fallback.hpp"
00011 #include "builder.hpp"
00012 #include "valid_integral_types.hpp"
00013
00014 namespace boost_atomic {
00015 namespace detail {
00016 namespace atomic {
00017
00018 static inline memory_order2 calculate_failure_order(memory_order2 order)
00019 {
00020 switch(order) {
00021 case memory_order2_acq_rel: return memory_order2_acquire;
00022 case memory_order2_release: return memory_order2_relaxed;
00023 default: return order;
00024 }
00025 }
00026
00027 template<typename T, unsigned short Size=sizeof(T)>
00028 class platform_atomic : public fallback_atomic<T> {
00029 public:
00030 typedef fallback_atomic<T> super;
00031
00032 explicit platform_atomic(T v) : super(v) {}
00033 platform_atomic() {}
00034 protected:
00035 typedef typename super::integral_type integral_type;
00036 };
00037
00038 template<typename T, unsigned short Size=sizeof(T)>
00039 class platform_atomic_integral : public build_atomic_from_exchange<fallback_atomic<T> > {
00040 public:
00041 typedef build_atomic_from_exchange<fallback_atomic<T> > super;
00042
00043 explicit platform_atomic_integral(T v) : super(v) {}
00044 platform_atomic_integral() {}
00045 protected:
00046 typedef typename super::integral_type integral_type;
00047 };
00048
00049 template<typename T>
00050 static inline void platform_atomic_thread_fence(T order)
00051 {
00052
00053
00054
00055 platform_atomic<int> a;
00056 a.exchange(0, order);
00057 }
00058
00059 template<typename T, unsigned short Size=sizeof(T), typename Int=typename is_integral_type<T>::test>
00060 class internal_atomic;
00061
00062 template<typename T, unsigned short Size>
00063 class internal_atomic<T, Size, void> : private detail::atomic::platform_atomic<T> {
00064 public:
00065 typedef detail::atomic::platform_atomic<T> super;
00066
00067 internal_atomic() {}
00068 explicit internal_atomic(T v) : super(v) {}
00069
00070 operator T(void) const volatile {return load();}
00071 T operator=(T v) volatile {store(v); return v;}
00072
00073 using super::is_lock_free;
00074 using super::load;
00075 using super::store;
00076 using super::exchange;
00077
00078 bool compare_exchange_strong(
00079 T &expected,
00080 T desired,
00081 memory_order2 order=memory_order2_seq_cst) volatile
00082 {
00083 return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
00084 }
00085 bool compare_exchange_weak(
00086 T &expected,
00087 T desired,
00088 memory_order2 order=memory_order2_seq_cst) volatile
00089 {
00090 return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
00091 }
00092 bool compare_exchange_strong(
00093 T &expected,
00094 T desired,
00095 memory_order2 success_order,
00096 memory_order2 failure_order) volatile
00097 {
00098 return super::compare_exchange_strong(expected, desired, success_order, failure_order);
00099 }
00100 bool compare_exchange_weak(
00101 T &expected,
00102 T desired,
00103 memory_order2 success_order,
00104 memory_order2 failure_order) volatile
00105 {
00106 return super::compare_exchange_strong(expected, desired, success_order, failure_order);
00107 }
00108 private:
00109 internal_atomic(const internal_atomic &);
00110 void operator=(const internal_atomic &);
00111 };
00112
00113 template<typename T, unsigned short Size>
00114 class internal_atomic<T, Size, int> : private detail::atomic::platform_atomic_integral<T> {
00115 public:
00116 typedef detail::atomic::platform_atomic_integral<T> super;
00117 typedef typename super::integral_type integral_type;
00118
00119 internal_atomic() {}
00120 explicit internal_atomic(T v) : super(v) {}
00121
00122 using super::is_lock_free;
00123 using super::load;
00124 using super::store;
00125 using super::exchange;
00126 using super::fetch_add;
00127 using super::fetch_sub;
00128 using super::fetch_and;
00129 using super::fetch_or;
00130 using super::fetch_xor;
00131
00132 operator integral_type(void) const volatile {return load();}
00133 integral_type operator=(integral_type v) volatile {store(v); return v;}
00134
00135 integral_type operator&=(integral_type c) volatile {return fetch_and(c)&c;}
00136 integral_type operator|=(integral_type c) volatile {return fetch_or(c)|c;}
00137 integral_type operator^=(integral_type c) volatile {return fetch_xor(c)^c;}
00138
00139 integral_type operator+=(integral_type c) volatile {return fetch_add(c)+c;}
00140 integral_type operator-=(integral_type c) volatile {return fetch_sub(c)-c;}
00141
00142 integral_type operator++(void) volatile {return fetch_add(1)+1;}
00143 integral_type operator++(int) volatile {return fetch_add(1);}
00144 integral_type operator--(void) volatile {return fetch_sub(1)-1;}
00145 integral_type operator--(int) volatile {return fetch_sub(1);}
00146
00147 bool compare_exchange_strong(
00148 integral_type &expected,
00149 integral_type desired,
00150 memory_order2 order=memory_order2_seq_cst) volatile
00151 {
00152 return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
00153 }
00154 bool compare_exchange_weak(
00155 integral_type &expected,
00156 integral_type desired,
00157 memory_order2 order=memory_order2_seq_cst) volatile
00158 {
00159 return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
00160 }
00161 bool compare_exchange_strong(
00162 integral_type &expected,
00163 integral_type desired,
00164 memory_order2 success_order,
00165 memory_order2 failure_order) volatile
00166 {
00167 return super::compare_exchange_strong(expected, desired, success_order, failure_order);
00168 }
00169 bool compare_exchange_weak(
00170 integral_type &expected,
00171 integral_type desired,
00172 memory_order2 success_order,
00173 memory_order2 failure_order) volatile
00174 {
00175 return super::compare_exchange_strong(expected, desired, success_order, failure_order);
00176 }
00177 private:
00178 internal_atomic(const internal_atomic &);
00179 void operator=(const internal_atomic &);
00180 };
00181
00182 }
00183 }
00184 }
00185
00186 #endif