00001 #ifndef BOOST_DETAIL_ATOMIC_BASE_HPP
00002 #define BOOST_DETAIL_ATOMIC_BASE_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015
00016 #include <boost/memory_order.hpp>
00017 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
00018
00019 #define BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
00020 operator value_type(void) volatile const \
00021 { \
00022 return load(memory_order_seq_cst); \
00023 } \
00024 \
00025 this_type & \
00026 operator=(value_type v) volatile \
00027 { \
00028 store(v, memory_order_seq_cst); \
00029 return *const_cast<this_type *>(this); \
00030 } \
00031 \
00032 bool \
00033 compare_exchange_strong( \
00034 value_type & expected, \
00035 value_type desired, \
00036 memory_order order = memory_order_seq_cst) volatile \
00037 { \
00038 return compare_exchange_strong(expected, desired, order, calculate_failure_order(order)); \
00039 } \
00040 \
00041 bool \
00042 compare_exchange_weak( \
00043 value_type & expected, \
00044 value_type desired, \
00045 memory_order order = memory_order_seq_cst) volatile \
00046 { \
00047 return compare_exchange_weak(expected, desired, order, calculate_failure_order(order)); \
00048 } \
00049 \
00050
00051 #define BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
00052 value_type \
00053 operator++(int) volatile \
00054 { \
00055 return fetch_add(1); \
00056 } \
00057 \
00058 value_type \
00059 operator++(void) volatile \
00060 { \
00061 return fetch_add(1) + 1; \
00062 } \
00063 \
00064 value_type \
00065 operator--(int) volatile \
00066 { \
00067 return fetch_sub(1); \
00068 } \
00069 \
00070 value_type \
00071 operator--(void) volatile \
00072 { \
00073 return fetch_sub(1) - 1; \
00074 } \
00075 \
00076 value_type \
00077 operator+=(difference_type v) volatile \
00078 { \
00079 return fetch_add(v) + v; \
00080 } \
00081 \
00082 value_type \
00083 operator-=(difference_type v) volatile \
00084 { \
00085 return fetch_sub(v) - v; \
00086 } \
00087
00088 #define BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
00089 value_type \
00090 operator&=(difference_type v) volatile \
00091 { \
00092 return fetch_and(v) & v; \
00093 } \
00094 \
00095 value_type \
00096 operator|=(difference_type v) volatile \
00097 { \
00098 return fetch_or(v) | v; \
00099 } \
00100 \
00101 value_type \
00102 operator^=(difference_type v) volatile \
00103 { \
00104 return fetch_xor(v) ^ v; \
00105 } \
00106
00107 #define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS \
00108 BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
00109 BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
00110
00111 #define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS \
00112 BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
00113 BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
00114 BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
00115
00116 namespace boost {
00117 namespace detail {
00118 namespace atomic {
00119
00120 static inline memory_order
00121 calculate_failure_order(memory_order order)
00122 {
00123 switch(order) {
00124 case memory_order_acq_rel:
00125 return memory_order_acquire;
00126 case memory_order_release:
00127 return memory_order_relaxed;
00128 default:
00129 return order;
00130 }
00131 }
00132
00133 template<typename T, typename C , unsigned int Size, bool Sign>
00134 class base_atomic {
00135 private:
00136 typedef base_atomic this_type;
00137 typedef T value_type;
00138 typedef detail::spinlock_pool<0>::scoped_lock guard_type;
00139 public:
00140 base_atomic(void) {}
00141
00142 explicit base_atomic(const value_type & v)
00143 {
00144 memcpy(&v_, &v, Size);
00145 }
00146
00147 void
00148 store(value_type v, memory_order = memory_order_seq_cst) volatile
00149 {
00150 guard_type guard(const_cast<char *>(v_));
00151
00152 memcpy(const_cast<char *>(v_), &v, Size);
00153 }
00154
00155 value_type
00156 load(memory_order = memory_order_seq_cst) volatile const
00157 {
00158 guard_type guard(const_cast<const char *>(v_));
00159
00160 value_type v;
00161 memcpy(&v, const_cast<const char *>(v_), Size);
00162 return v;
00163 }
00164
00165 bool
00166 compare_exchange_strong(
00167 value_type & expected,
00168 value_type desired,
00169 memory_order ,
00170 memory_order ) volatile
00171 {
00172 guard_type guard(const_cast<char *>(v_));
00173
00174 if (memcmp(const_cast<char *>(v_), &expected, Size) == 0) {
00175 memcpy(const_cast<char *>(v_), &desired, Size);
00176 return true;
00177 } else {
00178 memcpy(&expected, const_cast<char *>(v_), Size);
00179 return false;
00180 }
00181 }
00182
00183 bool
00184 compare_exchange_weak(
00185 value_type & expected,
00186 value_type desired,
00187 memory_order success_order,
00188 memory_order failure_order) volatile
00189 {
00190 return compare_exchange_strong(expected, desired, success_order, failure_order);
00191 }
00192
00193 value_type
00194 exchange(value_type v, memory_order =memory_order_seq_cst) volatile
00195 {
00196 guard_type guard(const_cast<char *>(v_));
00197
00198 value_type tmp;
00199 memcpy(&tmp, const_cast<char *>(v_), Size);
00200
00201 memcpy(const_cast<char *>(v_), &v, Size);
00202 return tmp;
00203 }
00204
00205 bool
00206 is_lock_free(void) const volatile
00207 {
00208 return false;
00209 }
00210
00211 BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00212 private:
00213 base_atomic(const base_atomic &) ;
00214 void operator=(const base_atomic &) ;
00215
00216 char v_[Size];
00217 };
00218
00219 template<typename T, unsigned int Size, bool Sign>
00220 class base_atomic<T, int, Size, Sign> {
00221 private:
00222 typedef base_atomic this_type;
00223 typedef T value_type;
00224 typedef T difference_type;
00225 typedef detail::spinlock_pool<0>::scoped_lock guard_type;
00226 public:
00227 explicit base_atomic(value_type v) : v_(v) {}
00228 base_atomic(void) {}
00229
00230 void
00231 store(value_type v, memory_order = memory_order_seq_cst) volatile
00232 {
00233 guard_type guard(const_cast<value_type *>(&v_));
00234
00235 v_ = v;
00236 }
00237
00238 value_type
00239 load(memory_order = memory_order_seq_cst) const volatile
00240 {
00241 guard_type guard(const_cast<value_type *>(&v_));
00242
00243 value_type v = const_cast<const volatile value_type &>(v_);
00244 return v;
00245 }
00246
00247 value_type
00248 exchange(value_type v, memory_order = memory_order_seq_cst) volatile
00249 {
00250 guard_type guard(const_cast<value_type *>(&v_));
00251
00252 value_type old = v_;
00253 v_ = v;
00254 return old;
00255 }
00256
00257 bool
00258 compare_exchange_strong(value_type & expected, value_type desired,
00259 memory_order ,
00260 memory_order ) volatile
00261 {
00262 guard_type guard(const_cast<value_type *>(&v_));
00263
00264 if (v_ == expected) {
00265 v_ = desired;
00266 return true;
00267 } else {
00268 expected = v_;
00269 return false;
00270 }
00271 }
00272
00273 bool
00274 compare_exchange_weak(value_type & expected, value_type desired,
00275 memory_order success_order,
00276 memory_order failure_order) volatile
00277 {
00278 return compare_exchange_strong(expected, desired, success_order, failure_order);
00279 }
00280
00281 value_type
00282 fetch_add(difference_type v, memory_order = memory_order_seq_cst) volatile
00283 {
00284 guard_type guard(const_cast<value_type *>(&v_));
00285
00286 value_type old = v_;
00287 v_ += v;
00288 return old;
00289 }
00290
00291 value_type
00292 fetch_sub(difference_type v, memory_order = memory_order_seq_cst) volatile
00293 {
00294 guard_type guard(const_cast<value_type *>(&v_));
00295
00296 value_type old = v_;
00297 v_ -= v;
00298 return old;
00299 }
00300
00301 value_type
00302 fetch_and(value_type v, memory_order = memory_order_seq_cst) volatile
00303 {
00304 guard_type guard(const_cast<value_type *>(&v_));
00305
00306 value_type old = v_;
00307 v_ &= v;
00308 return old;
00309 }
00310
00311 value_type
00312 fetch_or(value_type v, memory_order = memory_order_seq_cst) volatile
00313 {
00314 guard_type guard(const_cast<value_type *>(&v_));
00315
00316 value_type old = v_;
00317 v_ |= v;
00318 return old;
00319 }
00320
00321 value_type
00322 fetch_xor(value_type v, memory_order = memory_order_seq_cst) volatile
00323 {
00324 guard_type guard(const_cast<value_type *>(&v_));
00325
00326 value_type old = v_;
00327 v_ ^= v;
00328 return old;
00329 }
00330
00331 bool
00332 is_lock_free(void) const volatile
00333 {
00334 return false;
00335 }
00336
00337 BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
00338 private:
00339 base_atomic(const base_atomic &) ;
00340 void operator=(const base_atomic &) ;
00341 value_type v_;
00342 };
00343
00344 template<typename T, unsigned int Size, bool Sign>
00345 class base_atomic<T *, void *, Size, Sign> {
00346 private:
00347 typedef base_atomic this_type;
00348 typedef T * value_type;
00349 typedef ptrdiff_t difference_type;
00350 typedef detail::spinlock_pool<0>::scoped_lock guard_type;
00351 public:
00352 explicit base_atomic(value_type v) : v_(v) {}
00353 base_atomic(void) {}
00354
00355 void
00356 store(value_type v, memory_order = memory_order_seq_cst) volatile
00357 {
00358 guard_type guard(const_cast<value_type *>(&v_));
00359 v_ = v;
00360 }
00361
00362 value_type
00363 load(memory_order = memory_order_seq_cst) const volatile
00364 {
00365 guard_type guard(const_cast<value_type *>(&v_));
00366
00367 value_type v = const_cast<const volatile value_type &>(v_);
00368 return v;
00369 }
00370
00371 value_type
00372 exchange(value_type v, memory_order = memory_order_seq_cst) volatile
00373 {
00374 guard_type guard(const_cast<value_type *>(&v_));
00375
00376 value_type old = v_;
00377 v_ = v;
00378 return old;
00379 }
00380
00381 bool
00382 compare_exchange_strong(value_type & expected, value_type desired,
00383 memory_order ,
00384 memory_order ) volatile
00385 {
00386 guard_type guard(const_cast<value_type *>(&v_));
00387
00388 if (v_ == expected) {
00389 v_ = desired;
00390 return true;
00391 } else {
00392 expected = v_;
00393 return false;
00394 }
00395 }
00396
00397 bool
00398 compare_exchange_weak(value_type & expected, value_type desired,
00399 memory_order success_order,
00400 memory_order failure_order) volatile
00401 {
00402 return compare_exchange_strong(expected, desired, success_order, failure_order);
00403 }
00404
00405 value_type fetch_add(difference_type v, memory_order = memory_order_seq_cst) volatile
00406 {
00407 guard_type guard(const_cast<value_type *>(&v_));
00408
00409 value_type old = v_;
00410 v_ += v;
00411 return old;
00412 }
00413
00414 value_type fetch_sub(difference_type v, memory_order = memory_order_seq_cst) volatile
00415 {
00416 guard_type guard(const_cast<value_type *>(&v_));
00417
00418 value_type old = v_;
00419 v_ -= v;
00420 return old;
00421 }
00422
00423 bool
00424 is_lock_free(void) const volatile
00425 {
00426 return false;
00427 }
00428
00429 BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
00430 private:
00431 base_atomic(const base_atomic &) ;
00432 void operator=(const base_atomic &) ;
00433 value_type v_;
00434 };
00435
00436 template<unsigned int Size, bool Sign>
00437 class base_atomic<void *, void *, Size, Sign> {
00438 private:
00439 typedef base_atomic this_type;
00440 typedef void * value_type;
00441 typedef detail::spinlock_pool<0>::scoped_lock guard_type;
00442 public:
00443 explicit base_atomic(value_type v) : v_(v) {}
00444 base_atomic(void) {}
00445
00446 void
00447 store(value_type v, memory_order = memory_order_seq_cst) volatile
00448 {
00449 guard_type guard(const_cast<value_type *>(&v_));
00450 v_ = v;
00451 }
00452
00453 value_type
00454 load(memory_order = memory_order_seq_cst) const volatile
00455 {
00456 guard_type guard(const_cast<value_type *>(&v_));
00457
00458 value_type v = const_cast<const volatile value_type &>(v_);
00459 return v;
00460 }
00461
00462 value_type
00463 exchange(value_type v, memory_order = memory_order_seq_cst) volatile
00464 {
00465 guard_type guard(const_cast<value_type *>(&v_));
00466
00467 value_type old = v_;
00468 v_ = v;
00469 return old;
00470 }
00471
00472 bool
00473 compare_exchange_strong(value_type & expected, value_type desired,
00474 memory_order ,
00475 memory_order ) volatile
00476 {
00477 guard_type guard(const_cast<value_type *>(&v_));
00478
00479 if (v_ == expected) {
00480 v_ = desired;
00481 return true;
00482 } else {
00483 expected = v_;
00484 return false;
00485 }
00486 }
00487
00488 bool
00489 compare_exchange_weak(value_type & expected, value_type desired,
00490 memory_order success_order,
00491 memory_order failure_order) volatile
00492 {
00493 return compare_exchange_strong(expected, desired, success_order, failure_order);
00494 }
00495
00496 bool
00497 is_lock_free(void) const volatile
00498 {
00499 return false;
00500 }
00501
00502 BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00503 private:
00504 base_atomic(const base_atomic &) ;
00505 void operator=(const base_atomic &) ;
00506 value_type v_;
00507 };
00508
00509 }
00510 }
00511 }
00512
00513 #endif