cas64strong.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
00002 #define BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
00003 
00004 //  Distributed under the Boost Software License, Version 1.0.
00005 //  See accompanying file LICENSE_1_0.txt or copy at
00006 //  http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 //  Copyright (c) 2011 Helge Bahmann
00009 
00010 // Build 64-bit atomic operation from platform_cmpxchg64_strong
00011 // primitive. It is assumed that 64-bit loads/stores are not
00012 // atomic, so they are funnelled through cmpxchg as well.
00013 
00014 #include <boost/memory_order.hpp>
00015 #include <boost/atomic/detail/base.hpp>
00016 
00017 namespace boost {
00018 namespace detail {
00019 namespace atomic {
00020 
00021 /* integral types */
00022 
00023 template<typename T, bool Sign>
00024 class base_atomic<T, int, 8, Sign> {
00025         typedef base_atomic this_type;
00026         typedef T value_type;
00027         typedef T difference_type;
00028 public:
00029         explicit base_atomic(value_type v) : v_(v) {}
00030         base_atomic(void) {}
00031         
00032         void
00033         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00034         {
00035                 value_type expected = v_;
00036                 do {
00037                 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
00038         }
00039         
00040         value_type
00041         load(memory_order order = memory_order_seq_cst) const volatile
00042         {
00043                 value_type v = const_cast<const volatile value_type &>(v_);
00044                 do {
00045                 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
00046                 return v;
00047         }
00048         
00049         value_type
00050         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00051         {
00052                 value_type original = load(memory_order_relaxed);
00053                 do {
00054                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00055                 return original;
00056         }
00057         
00058         bool
00059         compare_exchange_weak(
00060                 value_type & expected,
00061                 value_type desired,
00062                 memory_order success_order,
00063                 memory_order failure_order) volatile
00064         {
00065                 return compare_exchange_strong(expected, desired, success_order, failure_order);
00066         }
00067         
00068         bool
00069         compare_exchange_strong(
00070                 value_type & expected,
00071                 value_type desired,
00072                 memory_order success_order,
00073                 memory_order failure_order) volatile
00074         {
00075                 platform_fence_before(success_order);
00076                 
00077                 bool success = platform_cmpxchg64_strong(expected, desired, &v_);
00078                 
00079                 if (success) {
00080                         platform_fence_after(success_order);
00081                 } else {
00082                         platform_fence_after(failure_order);
00083                 }
00084                 
00085                 return success;
00086         }
00087         
00088         value_type
00089         fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
00090         {
00091                 value_type original = load(memory_order_relaxed);
00092                 do {
00093                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00094                 return original;
00095         }
00096         
00097         value_type
00098         fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
00099         {
00100                 value_type original = load(memory_order_relaxed);
00101                 do {
00102                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00103                 return original;
00104         }
00105         
00106         value_type
00107         fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
00108         {
00109                 value_type original = load(memory_order_relaxed);
00110                 do {
00111                 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
00112                 return original;
00113         }
00114         
00115         value_type
00116         fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
00117         {
00118                 value_type original = load(memory_order_relaxed);
00119                 do {
00120                 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
00121                 return original;
00122         }
00123         
00124         value_type
00125         fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
00126         {
00127                 value_type original = load(memory_order_relaxed);
00128                 do {
00129                 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
00130                 return original;
00131         }
00132         
00133         bool
00134         is_lock_free(void) const volatile
00135         {
00136                 return true;
00137         }
00138         
00139         BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
00140 private:
00141         base_atomic(const base_atomic &) /* = delete */ ;
00142         void operator=(const base_atomic &) /* = delete */ ;
00143         value_type v_;
00144 };
00145 
00146 /* pointer types */
00147 
00148 template<bool Sign>
00149 class base_atomic<void *, void *, 8, Sign> {
00150         typedef base_atomic this_type;
00151         typedef void * value_type;
00152         typedef ptrdiff_t difference_type;
00153 public:
00154         explicit base_atomic(value_type v) : v_(v) {}
00155         base_atomic(void) {}
00156         
00157         void
00158         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00159         {
00160                 value_type expected = v_;
00161                 do {
00162                 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
00163         }
00164         
00165         value_type
00166         load(memory_order order = memory_order_seq_cst) const volatile
00167         {
00168                 value_type v = const_cast<const volatile value_type &>(v_);
00169                 do {
00170                 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
00171                 return v;
00172         }
00173         
00174         value_type
00175         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00176         {
00177                 value_type original = load(memory_order_relaxed);
00178                 do {
00179                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00180                 return original;
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         bool
00194         compare_exchange_strong(
00195                 value_type & expected,
00196                 value_type desired,
00197                 memory_order success_order,
00198                 memory_order failure_order) volatile
00199         {
00200                 platform_fence_before(success_order);
00201                 
00202                 bool success = platform_cmpxchg64_strong(expected, desired, &v_);
00203                 
00204                 if (success) {
00205                         platform_fence_after(success_order);
00206                 } else {
00207                         platform_fence_after(failure_order);
00208                 }
00209                 
00210                 return success;
00211         }
00212         
00213         value_type
00214         fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
00215         {
00216                 value_type original = load(memory_order_relaxed);
00217                 do {
00218                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00219                 return original;
00220         }
00221         
00222         value_type
00223         fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
00224         {
00225                 value_type original = load(memory_order_relaxed);
00226                 do {
00227                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00228                 return original;
00229         }
00230         
00231         bool
00232         is_lock_free(void) const volatile
00233         {
00234                 return true;
00235         }
00236         
00237         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00238 private:
00239         base_atomic(const base_atomic &) /* = delete */ ;
00240         void operator=(const base_atomic &) /* = delete */ ;
00241         value_type v_;
00242 };
00243 
00244 template<typename T, bool Sign>
00245 class base_atomic<T *, void *, 8, Sign> {
00246         typedef base_atomic this_type;
00247         typedef T * value_type;
00248         typedef ptrdiff_t difference_type;
00249 public:
00250         explicit base_atomic(value_type v) : v_(v) {}
00251         base_atomic(void) {}
00252         
00253         void
00254         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00255         {
00256                 value_type expected = v_;
00257                 do {
00258                 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
00259         }
00260         
00261         value_type
00262         load(memory_order order = memory_order_seq_cst) const volatile
00263         {
00264                 value_type v = const_cast<const volatile value_type &>(v_);
00265                 do {
00266                 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
00267                 return v;
00268         }
00269         
00270         value_type
00271         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00272         {
00273                 value_type original = load(memory_order_relaxed);
00274                 do {
00275                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00276                 return original;
00277         }
00278         
00279         bool
00280         compare_exchange_weak(
00281                 value_type & expected,
00282                 value_type desired,
00283                 memory_order success_order,
00284                 memory_order failure_order) volatile
00285         {
00286                 return compare_exchange_strong(expected, desired, success_order, failure_order);
00287         }
00288         
00289         bool
00290         compare_exchange_strong(
00291                 value_type & expected,
00292                 value_type desired,
00293                 memory_order success_order,
00294                 memory_order failure_order) volatile
00295         {
00296                 platform_fence_before(success_order);
00297                 
00298                 bool success = platform_cmpxchg64_strong(expected, desired, &v_);
00299                 
00300                 if (success) {
00301                         platform_fence_after(success_order);
00302                 } else {
00303                         platform_fence_after(failure_order);
00304                 }
00305                 
00306                 return success;
00307         }
00308         
00309         value_type
00310         fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
00311         {
00312                 value_type original = load(memory_order_relaxed);
00313                 do {
00314                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00315                 return original;
00316         }
00317         
00318         value_type
00319         fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
00320         {
00321                 value_type original = load(memory_order_relaxed);
00322                 do {
00323                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00324                 return original;
00325         }
00326         
00327         bool
00328         is_lock_free(void) const volatile
00329         {
00330                 return true;
00331         }
00332         
00333         BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
00334 private:
00335         base_atomic(const base_atomic &) /* = delete */ ;
00336         void operator=(const base_atomic &) /* = delete */ ;
00337         value_type v_;
00338 };
00339 
00340 /* generic types */
00341 
00342 template<typename T, bool Sign>
00343 class base_atomic<T, void, 8, Sign> {
00344         typedef base_atomic this_type;
00345         typedef T value_type;
00346         typedef uint64_t storage_type;
00347 public:
00348         explicit base_atomic(value_type v) : v_(0)
00349         {
00350                 memcpy(&v_, &v, sizeof(value_type));
00351         }
00352         base_atomic(void) : v_(0) {}
00353         
00354         void
00355         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00356         {
00357                 value_type expected;
00358                 memcpy(&expected, const_cast<storage_type *>(&v_), sizeof(value_type));
00359                 do {
00360                 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
00361         }
00362         
00363         value_type
00364         load(memory_order order = memory_order_seq_cst) const volatile
00365         {
00366                 value_type v;
00367                 memcpy(&v, const_cast<storage_type *>(&v_), sizeof(value_type));
00368                 do {
00369                 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
00370                 return v;
00371         }
00372         
00373         value_type
00374         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00375         {
00376                 value_type original = load(memory_order_relaxed);
00377                 do {
00378                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00379                 return original;
00380         }
00381         
00382         bool
00383         compare_exchange_weak(
00384                 value_type & expected,
00385                 value_type desired,
00386                 memory_order success_order,
00387                 memory_order failure_order) volatile
00388         {
00389                 return compare_exchange_strong(expected, desired, success_order, failure_order);
00390         }
00391         
00392         bool
00393         compare_exchange_strong(
00394                 value_type & expected,
00395                 value_type desired,
00396                 memory_order success_order,
00397                 memory_order failure_order) volatile
00398         {
00399                 
00400                 storage_type expected_s = 0, desired_s = 0;
00401                 memcpy(&expected_s, &expected, sizeof(value_type));
00402                 memcpy(&desired_s, &desired, sizeof(value_type));
00403                 
00404                 platform_fence_before(success_order);
00405                 bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
00406                 
00407                 if (success) {
00408                         platform_fence_after(success_order);
00409                 } else {
00410                         platform_fence_after(failure_order);
00411                         memcpy(&expected, &expected_s, sizeof(value_type));
00412                 }
00413                 
00414                 return success;
00415         }
00416         
00417         bool
00418         is_lock_free(void) const volatile
00419         {
00420                 return true;
00421         }
00422         
00423         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00424 private:
00425         base_atomic(const base_atomic &) /* = delete */ ;
00426         void operator=(const base_atomic &) /* = delete */ ;
00427         storage_type v_;
00428 };
00429 
00430 }
00431 }
00432 }
00433 
00434 #endif


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