$search
00001 #ifndef BOOST_DETAIL_ATOMIC_BASE_HPP 00002 #define BOOST_DETAIL_ATOMIC_BASE_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 // Base class definition and fallback implementation. 00011 // To be overridden (through partial specialization) by 00012 // platform implementations. 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 /*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 /*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 /*success_order*/, 00170 memory_order /*failure_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 /*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 &) /* = delete */ ; 00214 void operator=(const base_atomic &) /* = delete */ ; 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 /*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 /*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 /*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 /*success_order*/, 00260 memory_order /*failure_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 /*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 /*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 /*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 /*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 /*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 &) /* = delete */ ; 00340 void operator=(const base_atomic &) /* = delete */ ; 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 /*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 /*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 /*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 /*success_order*/, 00384 memory_order /*failure_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 /*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 /*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 &) /* = delete */ ; 00432 void operator=(const base_atomic &) /* = delete */ ; 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 /*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 /*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 /*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 /*success_order*/, 00475 memory_order /*failure_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 &) /* = delete */ ; 00505 void operator=(const base_atomic &) /* = delete */ ; 00506 value_type v_; 00507 }; 00508 00509 } 00510 } 00511 } 00512 00513 #endif