cas32weak.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_DETAIL_ATOMIC_CAS32WEAK_HPP
00002 #define BOOST_DETAIL_ATOMIC_CAS32WEAK_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 #include <boost/memory_order.hpp>
00011 #include <boost/atomic/detail/base.hpp>
00012 
00013 namespace boost {
00014 namespace detail {
00015 namespace atomic {
00016 
00017 /* integral types */
00018 
00019 template<typename T, bool Sign>
00020 class base_atomic<T, int, 1, Sign> {
00021         typedef base_atomic this_type;
00022         typedef T value_type;
00023         typedef T difference_type;
00024         typedef uint32_t storage_type;
00025 public:
00026         explicit base_atomic(value_type v) : v_(v) {}
00027         base_atomic(void) {}
00028         
00029         void
00030         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00031         {
00032                 platform_fence_before_store(order);
00033                 const_cast<volatile storage_type &>(v_) = v;
00034                 platform_fence_after_store(order);
00035         }
00036         
00037         value_type
00038         load(memory_order order = memory_order_seq_cst) const volatile
00039         {
00040                 value_type v = const_cast<const volatile storage_type &>(v_);
00041                 platform_fence_after_load(order);
00042                 return v;
00043         }
00044         
00045         value_type
00046         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00047         {
00048                 value_type original = load(memory_order_relaxed);
00049                 do {
00050                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00051                 return original;
00052         }
00053         
00054         bool
00055         compare_exchange_weak(
00056                 value_type & expected,
00057                 value_type desired,
00058                 memory_order success_order,
00059                 memory_order failure_order) volatile
00060         {
00061                 platform_fence_before(success_order);
00062                 
00063                 storage_type expected_s = (storage_type) expected;
00064                 storage_type desired_s = (storage_type) desired;
00065                 
00066                 bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
00067                 
00068                 if (success) {
00069                         platform_fence_after(success_order);
00070                 } else {
00071                         platform_fence_after(failure_order);
00072                         expected = (value_type) expected_s;
00073                 }
00074                 
00075                 return success;
00076         }
00077         
00078         bool
00079         compare_exchange_strong(
00080                 value_type & expected,
00081                 value_type desired,
00082                 memory_order success_order,
00083                 memory_order failure_order) volatile
00084         {
00085                 for(;;) {
00086                         value_type tmp = expected;
00087                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00088                                 return true;
00089                         if (tmp != expected) {
00090                                 expected = tmp;
00091                                 return false;
00092                         }
00093                 }
00094         }
00095         
00096         value_type
00097         fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
00098         {
00099                 value_type original = load(memory_order_relaxed);
00100                 do {
00101                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00102                 return original;
00103         }
00104         
00105         value_type
00106         fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
00107         {
00108                 value_type original = load(memory_order_relaxed);
00109                 do {
00110                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00111                 return original;
00112         }
00113         
00114         value_type
00115         fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
00116         {
00117                 value_type original = load(memory_order_relaxed);
00118                 do {
00119                 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
00120                 return original;
00121         }
00122         
00123         value_type
00124         fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
00125         {
00126                 value_type original = load(memory_order_relaxed);
00127                 do {
00128                 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
00129                 return original;
00130         }
00131         
00132         value_type
00133         fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
00134         {
00135                 value_type original = load(memory_order_relaxed);
00136                 do {
00137                 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
00138                 return original;
00139         }
00140         
00141         bool
00142         is_lock_free(void) const volatile
00143         {
00144                 return true;
00145         }
00146         
00147         BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
00148 private:
00149         base_atomic(const base_atomic &) /* = delete */ ;
00150         void operator=(const base_atomic &) /* = delete */ ;
00151         storage_type v_;
00152 };
00153 
00154 template<typename T, bool Sign>
00155 class base_atomic<T, int, 2, Sign> {
00156         typedef base_atomic this_type;
00157         typedef T value_type;
00158         typedef T difference_type;
00159         typedef uint32_t storage_type;
00160 public:
00161         explicit base_atomic(value_type v) : v_(v) {}
00162         base_atomic(void) {}
00163         
00164         void
00165         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00166         {
00167                 platform_fence_before_store(order);
00168                 const_cast<volatile storage_type &>(v_) = v;
00169                 platform_fence_after_store(order);
00170         }
00171         
00172         value_type
00173         load(memory_order order = memory_order_seq_cst) const volatile
00174         {
00175                 value_type v = const_cast<const volatile storage_type &>(v_);
00176                 platform_fence_after_load(order);
00177                 return v;
00178         }
00179         
00180         value_type
00181         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00182         {
00183                 value_type original = load(memory_order_relaxed);
00184                 do {
00185                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00186                 return original;
00187         }
00188         
00189         bool
00190         compare_exchange_weak(
00191                 value_type & expected,
00192                 value_type desired,
00193                 memory_order success_order,
00194                 memory_order failure_order) volatile
00195         {
00196                 platform_fence_before(success_order);
00197                 
00198                 storage_type expected_s = (storage_type) expected;
00199                 storage_type desired_s = (storage_type) desired;
00200                 
00201                 bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
00202                 
00203                 if (success) {
00204                         platform_fence_after(success_order);
00205                 } else {
00206                         platform_fence_after(failure_order);
00207                         expected = (value_type) expected_s;
00208                 }
00209                 
00210                 return success;
00211         }
00212         
00213         bool
00214         compare_exchange_strong(
00215                 value_type & expected,
00216                 value_type desired,
00217                 memory_order success_order,
00218                 memory_order failure_order) volatile
00219         {
00220                 for(;;) {
00221                         value_type tmp = expected;
00222                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00223                                 return true;
00224                         if (tmp != expected) {
00225                                 expected = tmp;
00226                                 return false;
00227                         }
00228                 }
00229         }
00230         
00231         value_type
00232         fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
00233         {
00234                 value_type original = load(memory_order_relaxed);
00235                 do {
00236                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00237                 return original;
00238         }
00239         
00240         value_type
00241         fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
00242         {
00243                 value_type original = load(memory_order_relaxed);
00244                 do {
00245                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00246                 return original;
00247         }
00248         
00249         value_type
00250         fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
00251         {
00252                 value_type original = load(memory_order_relaxed);
00253                 do {
00254                 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
00255                 return original;
00256         }
00257         
00258         value_type
00259         fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
00260         {
00261                 value_type original = load(memory_order_relaxed);
00262                 do {
00263                 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
00264                 return original;
00265         }
00266         
00267         value_type
00268         fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
00269         {
00270                 value_type original = load(memory_order_relaxed);
00271                 do {
00272                 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
00273                 return original;
00274         }
00275         
00276         bool
00277         is_lock_free(void) const volatile
00278         {
00279                 return true;
00280         }
00281         
00282         BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
00283 private:
00284         base_atomic(const base_atomic &) /* = delete */ ;
00285         void operator=(const base_atomic &) /* = delete */ ;
00286         storage_type v_;
00287 };
00288 
00289 template<typename T, bool Sign>
00290 class base_atomic<T, int, 4, Sign> {
00291         typedef base_atomic this_type;
00292         typedef T value_type;
00293         typedef T difference_type;
00294 public:
00295         explicit base_atomic(value_type v) : v_(v) {}
00296         base_atomic(void) {}
00297         
00298         void
00299         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00300         {
00301                 platform_fence_before_store(order);
00302                 const_cast<volatile value_type &>(v_) = v;
00303                 platform_fence_after_store(order);
00304         }
00305         
00306         value_type
00307         load(memory_order order = memory_order_seq_cst) const volatile
00308         {
00309                 value_type v = const_cast<const volatile value_type &>(v_);
00310                 platform_fence_after_load(order);
00311                 return v;
00312         }
00313         
00314         value_type
00315         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00316         {
00317                 value_type original = load(memory_order_relaxed);
00318                 do {
00319                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00320                 return original;
00321         }
00322         
00323         bool
00324         compare_exchange_weak(
00325                 value_type & expected,
00326                 value_type desired,
00327                 memory_order success_order,
00328                 memory_order failure_order) volatile
00329         {
00330                 platform_fence_before(success_order);
00331                 
00332                 bool success = platform_cmpxchg32(expected, desired, &v_);
00333                 
00334                 if (success) {
00335                         platform_fence_after(success_order);
00336                 } else {
00337                         platform_fence_after(failure_order);
00338                 }
00339                 
00340                 return success;
00341         }
00342         
00343         bool
00344         compare_exchange_strong(
00345                 value_type & expected,
00346                 value_type desired,
00347                 memory_order success_order,
00348                 memory_order failure_order) volatile
00349         {
00350                 for(;;) {
00351                         value_type tmp = expected;
00352                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00353                                 return true;
00354                         if (tmp != expected) {
00355                                 expected = tmp;
00356                                 return false;
00357                         }
00358                 }
00359         }
00360         
00361         value_type
00362         fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
00363         {
00364                 value_type original = load(memory_order_relaxed);
00365                 do {
00366                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00367                 return original;
00368         }
00369         
00370         value_type
00371         fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
00372         {
00373                 value_type original = load(memory_order_relaxed);
00374                 do {
00375                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00376                 return original;
00377         }
00378         
00379         value_type
00380         fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
00381         {
00382                 value_type original = load(memory_order_relaxed);
00383                 do {
00384                 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
00385                 return original;
00386         }
00387         
00388         value_type
00389         fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
00390         {
00391                 value_type original = load(memory_order_relaxed);
00392                 do {
00393                 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
00394                 return original;
00395         }
00396         
00397         value_type
00398         fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
00399         {
00400                 value_type original = load(memory_order_relaxed);
00401                 do {
00402                 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
00403                 return original;
00404         }
00405         
00406         bool
00407         is_lock_free(void) const volatile
00408         {
00409                 return true;
00410         }
00411         
00412         BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
00413 private:
00414         base_atomic(const base_atomic &) /* = delete */ ;
00415         void operator=(const base_atomic &) /* = delete */ ;
00416         value_type v_;
00417 };
00418 
00419 /* pointer types */
00420 
00421 template<bool Sign>
00422 class base_atomic<void *, void *, 4, Sign> {
00423         typedef base_atomic this_type;
00424         typedef void * value_type;
00425         typedef ptrdiff_t difference_type;
00426 public:
00427         explicit base_atomic(value_type v) : v_(v) {}
00428         base_atomic(void) {}
00429         
00430         void
00431         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00432         {
00433                 platform_fence_before_store(order);
00434                 const_cast<volatile value_type &>(v_) = v;
00435                 platform_fence_after_store(order);
00436         }
00437         
00438         value_type
00439         load(memory_order order = memory_order_seq_cst) const volatile
00440         {
00441                 value_type v = const_cast<const volatile value_type &>(v_);
00442                 platform_fence_after_load(order);
00443                 return v;
00444         }
00445         
00446         value_type
00447         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00448         {
00449                 value_type original = load(memory_order_relaxed);
00450                 do {
00451                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00452                 return original;
00453         }
00454         
00455         bool
00456         compare_exchange_weak(
00457                 value_type & expected,
00458                 value_type desired,
00459                 memory_order success_order,
00460                 memory_order failure_order) volatile
00461         {
00462                 platform_fence_before(success_order);
00463                 
00464                 bool success = platform_cmpxchg32(expected, desired, &v_);
00465                 
00466                 if (success) {
00467                         platform_fence_after(success_order);
00468                 } else {
00469                         platform_fence_after(failure_order);
00470                 }
00471                 
00472                 return success;
00473         }
00474         
00475         bool
00476         compare_exchange_strong(
00477                 value_type & expected,
00478                 value_type desired,
00479                 memory_order success_order,
00480                 memory_order failure_order) volatile
00481         {
00482                 for(;;) {
00483                         value_type tmp = expected;
00484                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00485                                 return true;
00486                         if (tmp != expected) {
00487                                 expected = tmp;
00488                                 return false;
00489                         }
00490                 }
00491         }
00492         
00493         value_type
00494         fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
00495         {
00496                 value_type original = load(memory_order_relaxed);
00497                 do {
00498                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00499                 return original;
00500         }
00501         
00502         value_type
00503         fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
00504         {
00505                 value_type original = load(memory_order_relaxed);
00506                 do {
00507                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00508                 return original;
00509         }
00510         
00511         bool
00512         is_lock_free(void) const volatile
00513         {
00514                 return true;
00515         }
00516         
00517         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00518 private:
00519         base_atomic(const base_atomic &) /* = delete */ ;
00520         void operator=(const base_atomic &) /* = delete */ ;
00521         value_type v_;
00522 };
00523 
00524 template<typename T, bool Sign>
00525 class base_atomic<T *, void *, 4, Sign> {
00526         typedef base_atomic this_type;
00527         typedef T * value_type;
00528         typedef ptrdiff_t difference_type;
00529 public:
00530         explicit base_atomic(value_type v) : v_(v) {}
00531         base_atomic(void) {}
00532         
00533         void
00534         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00535         {
00536                 platform_fence_before_store(order);
00537                 const_cast<volatile value_type &>(v_) = v;
00538                 platform_fence_after_store(order);
00539         }
00540         
00541         value_type
00542         load(memory_order order = memory_order_seq_cst) const volatile
00543         {
00544                 value_type v = const_cast<const volatile value_type &>(v_);
00545                 platform_fence_after_load(order);
00546                 return v;
00547         }
00548         
00549         value_type
00550         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00551         {
00552                 value_type original = load(memory_order_relaxed);
00553                 do {
00554                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00555                 return original;
00556         }
00557         
00558         bool
00559         compare_exchange_weak(
00560                 value_type & expected,
00561                 value_type desired,
00562                 memory_order success_order,
00563                 memory_order failure_order) volatile
00564         {
00565                 platform_fence_before(success_order);
00566                 
00567                 bool success = platform_cmpxchg32(expected, desired, &v_);
00568                 
00569                 if (success) {
00570                         platform_fence_after(success_order);
00571                 } else {
00572                         platform_fence_after(failure_order);
00573                 }
00574                 
00575                 return success;
00576         }
00577         
00578         bool
00579         compare_exchange_strong(
00580                 value_type & expected,
00581                 value_type desired,
00582                 memory_order success_order,
00583                 memory_order failure_order) volatile
00584         {
00585                 for(;;) {
00586                         value_type tmp = expected;
00587                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00588                                 return true;
00589                         if (tmp != expected) {
00590                                 expected = tmp;
00591                                 return false;
00592                         }
00593                 }
00594         }
00595         
00596         value_type
00597         fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
00598         {
00599                 value_type original = load(memory_order_relaxed);
00600                 do {
00601                 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
00602                 return original;
00603         }
00604         
00605         value_type
00606         fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
00607         {
00608                 value_type original = load(memory_order_relaxed);
00609                 do {
00610                 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
00611                 return original;
00612         }
00613         
00614         bool
00615         is_lock_free(void) const volatile
00616         {
00617                 return true;
00618         }
00619         
00620         BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
00621 private:
00622         base_atomic(const base_atomic &) /* = delete */ ;
00623         void operator=(const base_atomic &) /* = delete */ ;
00624         value_type v_;
00625 };
00626 
00627 /* generic types */
00628 
00629 template<typename T, bool Sign>
00630 class base_atomic<T, void, 1, Sign> {
00631         typedef base_atomic this_type;
00632         typedef T value_type;
00633         typedef uint32_t storage_type;
00634 public:
00635         explicit base_atomic(value_type v) : v_(0)
00636         {
00637                 memcpy(&v_, &v, sizeof(value_type));
00638         }
00639         base_atomic(void) : v_(0) {}
00640         
00641         void
00642         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00643         {
00644                 storage_type tmp = 0;
00645                 memcpy(&tmp, &v, sizeof(value_type));
00646                 platform_fence_before_store(order);
00647                 const_cast<volatile storage_type &>(v_) = tmp;
00648                 platform_fence_after_store(order);
00649         }
00650         
00651         value_type
00652         load(memory_order order = memory_order_seq_cst) const volatile
00653         {
00654                 storage_type tmp = const_cast<const volatile storage_type &>(v_);
00655                 platform_fence_after_load(order);
00656                 
00657                 value_type v;
00658                 memcpy(&v, &tmp, sizeof(value_type));
00659                 return v;
00660         }
00661         
00662         value_type
00663         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00664         {
00665                 value_type original = load(memory_order_relaxed);
00666                 do {
00667                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00668                 return original;
00669         }
00670         
00671         bool
00672         compare_exchange_weak(
00673                 value_type & expected,
00674                 value_type desired,
00675                 memory_order success_order,
00676                 memory_order failure_order) volatile
00677         {
00678                 storage_type expected_s = 0, desired_s = 0;
00679                 memcpy(&expected_s, &expected, sizeof(value_type));
00680                 memcpy(&desired_s, &desired, sizeof(value_type));
00681                 
00682                 platform_fence_before(success_order);
00683                 
00684                 bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
00685                 
00686                 if (success) {
00687                         platform_fence_after(success_order);
00688                 } else {
00689                         platform_fence_after(failure_order);
00690                         memcpy(&expected, &expected_s, sizeof(value_type));
00691                 }
00692                 
00693                 return success;
00694         }
00695         
00696         bool
00697         compare_exchange_strong(
00698                 value_type & expected,
00699                 value_type desired,
00700                 memory_order success_order,
00701                 memory_order failure_order) volatile
00702         {
00703                 for(;;) {
00704                         value_type tmp = expected;
00705                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00706                                 return true;
00707                         if (tmp != expected) {
00708                                 expected = tmp;
00709                                 return false;
00710                         }
00711                 }
00712         }
00713         
00714         bool
00715         is_lock_free(void) const volatile
00716         {
00717                 return true;
00718         }
00719         
00720         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00721 private:
00722         base_atomic(const base_atomic &) /* = delete */ ;
00723         void operator=(const base_atomic &) /* = delete */ ;
00724         storage_type v_;
00725 };
00726 
00727 template<typename T, bool Sign>
00728 class base_atomic<T, void, 2, Sign> {
00729         typedef base_atomic this_type;
00730         typedef T value_type;
00731         typedef uint32_t storage_type;
00732 public:
00733         explicit base_atomic(value_type v) : v_(0)
00734         {
00735                 memcpy(&v_, &v, sizeof(value_type));
00736         }
00737         base_atomic(void) : v_(0) {}
00738         
00739         void
00740         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00741         {
00742                 storage_type tmp = 0;
00743                 memcpy(&tmp, &v, sizeof(value_type));
00744                 platform_fence_before_store(order);
00745                 const_cast<volatile storage_type &>(v_) = tmp;
00746                 platform_fence_after_store(order);
00747         }
00748         
00749         value_type
00750         load(memory_order order = memory_order_seq_cst) const volatile
00751         {
00752                 storage_type tmp = const_cast<const volatile storage_type &>(v_);
00753                 platform_fence_after_load(order);
00754                 
00755                 value_type v;
00756                 memcpy(&v, &tmp, sizeof(value_type));
00757                 return v;
00758         }
00759         
00760         value_type
00761         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00762         {
00763                 value_type original = load(memory_order_relaxed);
00764                 do {
00765                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00766                 return original;
00767         }
00768         
00769         bool
00770         compare_exchange_weak(
00771                 value_type & expected,
00772                 value_type desired,
00773                 memory_order success_order,
00774                 memory_order failure_order) volatile
00775         {
00776                 storage_type expected_s = 0, desired_s = 0;
00777                 memcpy(&expected_s, &expected, sizeof(value_type));
00778                 memcpy(&desired_s, &desired, sizeof(value_type));
00779                 
00780                 platform_fence_before(success_order);
00781                 
00782                 bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
00783                 
00784                 if (success) {
00785                         platform_fence_after(success_order);
00786                 } else {
00787                         platform_fence_after(failure_order);
00788                         memcpy(&expected, &expected_s, sizeof(value_type));
00789                 }
00790                 
00791                 return success;
00792         }
00793         
00794         bool
00795         compare_exchange_strong(
00796                 value_type & expected,
00797                 value_type desired,
00798                 memory_order success_order,
00799                 memory_order failure_order) volatile
00800         {
00801                 for(;;) {
00802                         value_type tmp = expected;
00803                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00804                                 return true;
00805                         if (tmp != expected) {
00806                                 expected = tmp;
00807                                 return false;
00808                         }
00809                 }
00810         }
00811         
00812         bool
00813         is_lock_free(void) const volatile
00814         {
00815                 return true;
00816         }
00817         
00818         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00819 private:
00820         base_atomic(const base_atomic &) /* = delete */ ;
00821         void operator=(const base_atomic &) /* = delete */ ;
00822         storage_type v_;
00823 };
00824 
00825 template<typename T, bool Sign>
00826 class base_atomic<T, void, 4, Sign> {
00827         typedef base_atomic this_type;
00828         typedef T value_type;
00829         typedef uint32_t storage_type;
00830 public:
00831         explicit base_atomic(value_type v) : v_(0)
00832         {
00833                 memcpy(&v_, &v, sizeof(value_type));
00834         }
00835         base_atomic(void) : v_(0) {}
00836         
00837         void
00838         store(value_type v, memory_order order = memory_order_seq_cst) volatile
00839         {
00840                 storage_type tmp = 0;
00841                 memcpy(&tmp, &v, sizeof(value_type));
00842                 platform_fence_before_store(order);
00843                 const_cast<volatile storage_type &>(v_) = tmp;
00844                 platform_fence_after_store(order);
00845         }
00846         
00847         value_type
00848         load(memory_order order = memory_order_seq_cst) const volatile
00849         {
00850                 storage_type tmp = const_cast<const volatile storage_type &>(v_);
00851                 platform_fence_after_load(order);
00852                 
00853                 value_type v;
00854                 memcpy(&v, &tmp, sizeof(value_type));
00855                 return v;
00856         }
00857         
00858         value_type
00859         exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
00860         {
00861                 value_type original = load(memory_order_relaxed);
00862                 do {
00863                 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
00864                 return original;
00865         }
00866         
00867         bool
00868         compare_exchange_weak(
00869                 value_type & expected,
00870                 value_type desired,
00871                 memory_order success_order,
00872                 memory_order failure_order) volatile
00873         {
00874                 storage_type expected_s = 0, desired_s = 0;
00875                 memcpy(&expected_s, &expected, sizeof(value_type));
00876                 memcpy(&desired_s, &desired, sizeof(value_type));
00877                 
00878                 platform_fence_before(success_order);
00879                 
00880                 bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
00881                 
00882                 if (success) {
00883                         platform_fence_after(success_order);
00884                 } else {
00885                         platform_fence_after(failure_order);
00886                         memcpy(&expected, &expected_s, sizeof(value_type));
00887                 }
00888                 
00889                 return success;
00890         }
00891         
00892         bool
00893         compare_exchange_strong(
00894                 value_type & expected,
00895                 value_type desired,
00896                 memory_order success_order,
00897                 memory_order failure_order) volatile
00898         {
00899                 for(;;) {
00900                         value_type tmp = expected;
00901                         if (compare_exchange_weak(tmp, desired, success_order, failure_order))
00902                                 return true;
00903                         if (tmp != expected) {
00904                                 expected = tmp;
00905                                 return false;
00906                         }
00907                 }
00908         }
00909         
00910         bool
00911         is_lock_free(void) const volatile
00912         {
00913                 return true;
00914         }
00915         
00916         BOOST_ATOMIC_DECLARE_BASE_OPERATORS
00917 private:
00918         base_atomic(const base_atomic &) /* = delete */ ;
00919         void operator=(const base_atomic &) /* = delete */ ;
00920         storage_type v_;
00921 };
00922 
00923 }
00924 }
00925 }
00926 
00927 #endif


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