base.hpp
Go to the documentation of this file.
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


rosatomic
Author(s): Josh Faust
autogenerated on Sat Jun 8 2019 20:43:34