Home | History | Annotate | Download | only in atomics.types.generic
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // UNSUPPORTED: libcpp-has-no-threads
     11 
     12 // <atomic>
     13 
     14 // template <class T>
     15 // struct atomic
     16 // {
     17 //     bool is_lock_free() const volatile;
     18 //     bool is_lock_free() const;
     19 //     void store(T desr, memory_order m = memory_order_seq_cst) volatile;
     20 //     void store(T desr, memory_order m = memory_order_seq_cst);
     21 //     T load(memory_order m = memory_order_seq_cst) const volatile;
     22 //     T load(memory_order m = memory_order_seq_cst) const;
     23 //     operator T() const volatile;
     24 //     operator T() const;
     25 //     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile;
     26 //     T exchange(T desr, memory_order m = memory_order_seq_cst);
     27 //     bool compare_exchange_weak(T& expc, T desr,
     28 //                                memory_order s, memory_order f) volatile;
     29 //     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f);
     30 //     bool compare_exchange_strong(T& expc, T desr,
     31 //                                  memory_order s, memory_order f) volatile;
     32 //     bool compare_exchange_strong(T& expc, T desr,
     33 //                                  memory_order s, memory_order f);
     34 //     bool compare_exchange_weak(T& expc, T desr,
     35 //                                memory_order m = memory_order_seq_cst) volatile;
     36 //     bool compare_exchange_weak(T& expc, T desr,
     37 //                                memory_order m = memory_order_seq_cst);
     38 //     bool compare_exchange_strong(T& expc, T desr,
     39 //                                 memory_order m = memory_order_seq_cst) volatile;
     40 //     bool compare_exchange_strong(T& expc, T desr,
     41 //                                  memory_order m = memory_order_seq_cst);
     42 //
     43 //     atomic() = default;
     44 //     constexpr atomic(T desr);
     45 //     atomic(const atomic&) = delete;
     46 //     atomic& operator=(const atomic&) = delete;
     47 //     atomic& operator=(const atomic&) volatile = delete;
     48 //     T operator=(T) volatile;
     49 //     T operator=(T);
     50 // };
     51 //
     52 // typedef atomic<bool> atomic_bool;
     53 
     54 #include <atomic>
     55 #include <new>
     56 #include <cassert>
     57 
     58 #include <cmpxchg_loop.h>
     59 
     60 int main()
     61 {
     62     {
     63         volatile std::atomic<bool> obj(true);
     64         assert(obj == true);
     65         std::atomic_init(&obj, false);
     66         assert(obj == false);
     67         std::atomic_init(&obj, true);
     68         assert(obj == true);
     69         bool b0 = obj.is_lock_free();
     70         (void)b0; // to placate scan-build
     71         obj.store(false);
     72         assert(obj == false);
     73         obj.store(true, std::memory_order_release);
     74         assert(obj == true);
     75         assert(obj.load() == true);
     76         assert(obj.load(std::memory_order_acquire) == true);
     77         assert(obj.exchange(false) == true);
     78         assert(obj == false);
     79         assert(obj.exchange(true, std::memory_order_relaxed) == false);
     80         assert(obj == true);
     81         bool x = obj;
     82         assert(cmpxchg_weak_loop(obj, x, false) == true);
     83         assert(obj == false);
     84         assert(x == true);
     85         assert(obj.compare_exchange_weak(x, true,
     86                                          std::memory_order_seq_cst) == false);
     87         assert(obj == false);
     88         assert(x == false);
     89         obj.store(true);
     90         x = true;
     91         assert(cmpxchg_weak_loop(obj, x, false,
     92                                  std::memory_order_seq_cst,
     93                                  std::memory_order_seq_cst) == true);
     94         assert(obj == false);
     95         assert(x == true);
     96         x = true;
     97         obj.store(true);
     98         assert(obj.compare_exchange_strong(x, false) == true);
     99         assert(obj == false);
    100         assert(x == true);
    101         assert(obj.compare_exchange_strong(x, true,
    102                                          std::memory_order_seq_cst) == false);
    103         assert(obj == false);
    104         assert(x == false);
    105         x = true;
    106         obj.store(true);
    107         assert(obj.compare_exchange_strong(x, false,
    108                                            std::memory_order_seq_cst,
    109                                            std::memory_order_seq_cst) == true);
    110         assert(obj == false);
    111         assert(x == true);
    112         assert((obj = false) == false);
    113         assert(obj == false);
    114         assert((obj = true) == true);
    115         assert(obj == true);
    116     }
    117     {
    118         std::atomic<bool> obj(true);
    119         assert(obj == true);
    120         std::atomic_init(&obj, false);
    121         assert(obj == false);
    122         std::atomic_init(&obj, true);
    123         assert(obj == true);
    124         bool b0 = obj.is_lock_free();
    125         (void)b0; // to placate scan-build
    126         obj.store(false);
    127         assert(obj == false);
    128         obj.store(true, std::memory_order_release);
    129         assert(obj == true);
    130         assert(obj.load() == true);
    131         assert(obj.load(std::memory_order_acquire) == true);
    132         assert(obj.exchange(false) == true);
    133         assert(obj == false);
    134         assert(obj.exchange(true, std::memory_order_relaxed) == false);
    135         assert(obj == true);
    136         bool x = obj;
    137         assert(cmpxchg_weak_loop(obj, x, false) == true);
    138         assert(obj == false);
    139         assert(x == true);
    140         assert(obj.compare_exchange_weak(x, true,
    141                                          std::memory_order_seq_cst) == false);
    142         assert(obj == false);
    143         assert(x == false);
    144         obj.store(true);
    145         x = true;
    146         assert(cmpxchg_weak_loop(obj, x, false,
    147                                  std::memory_order_seq_cst,
    148                                  std::memory_order_seq_cst) == true);
    149         assert(obj == false);
    150         assert(x == true);
    151         x = true;
    152         obj.store(true);
    153         assert(obj.compare_exchange_strong(x, false) == true);
    154         assert(obj == false);
    155         assert(x == true);
    156         assert(obj.compare_exchange_strong(x, true,
    157                                          std::memory_order_seq_cst) == false);
    158         assert(obj == false);
    159         assert(x == false);
    160         x = true;
    161         obj.store(true);
    162         assert(obj.compare_exchange_strong(x, false,
    163                                            std::memory_order_seq_cst,
    164                                            std::memory_order_seq_cst) == true);
    165         assert(obj == false);
    166         assert(x == true);
    167         assert((obj = false) == false);
    168         assert(obj == false);
    169         assert((obj = true) == true);
    170         assert(obj == true);
    171     }
    172     {
    173         std::atomic_bool obj(true);
    174         assert(obj == true);
    175         std::atomic_init(&obj, false);
    176         assert(obj == false);
    177         std::atomic_init(&obj, true);
    178         assert(obj == true);
    179         bool b0 = obj.is_lock_free();
    180         (void)b0; // to placate scan-build
    181         obj.store(false);
    182         assert(obj == false);
    183         obj.store(true, std::memory_order_release);
    184         assert(obj == true);
    185         assert(obj.load() == true);
    186         assert(obj.load(std::memory_order_acquire) == true);
    187         assert(obj.exchange(false) == true);
    188         assert(obj == false);
    189         assert(obj.exchange(true, std::memory_order_relaxed) == false);
    190         assert(obj == true);
    191         bool x = obj;
    192         assert(cmpxchg_weak_loop(obj, x, false) == true);
    193         assert(obj == false);
    194         assert(x == true);
    195         assert(obj.compare_exchange_weak(x, true,
    196                                          std::memory_order_seq_cst) == false);
    197         assert(obj == false);
    198         assert(x == false);
    199         obj.store(true);
    200         x = true;
    201         assert(cmpxchg_weak_loop(obj, x, false,
    202                                  std::memory_order_seq_cst,
    203                                  std::memory_order_seq_cst) == true);
    204         assert(obj == false);
    205         assert(x == true);
    206         x = true;
    207         obj.store(true);
    208         assert(obj.compare_exchange_strong(x, false) == true);
    209         assert(obj == false);
    210         assert(x == true);
    211         assert(obj.compare_exchange_strong(x, true,
    212                                          std::memory_order_seq_cst) == false);
    213         assert(obj == false);
    214         assert(x == false);
    215         x = true;
    216         obj.store(true);
    217         assert(obj.compare_exchange_strong(x, false,
    218                                            std::memory_order_seq_cst,
    219                                            std::memory_order_seq_cst) == true);
    220         assert(obj == false);
    221         assert(x == true);
    222         assert((obj = false) == false);
    223         assert(obj == false);
    224         assert((obj = true) == true);
    225         assert(obj == true);
    226     }
    227     {
    228         typedef std::atomic<bool> A;
    229         _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
    230         A& zero = *new (storage) A();
    231         assert(zero == false);
    232         zero.~A();
    233     }
    234 }
    235