1f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant//===----------------------------------------------------------------------===// 2f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 3f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// The LLVM Compiler Infrastructure 4f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 5f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 8f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant//===----------------------------------------------------------------------===// 9f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 10f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// <atomic> 11f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 12f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// template <> 13f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// struct atomic<integral> 14f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// { 15f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool is_lock_free() const volatile; 16f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool is_lock_free() const; 17f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// void store(integral desr, memory_order m = memory_order_seq_cst) volatile; 18f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// void store(integral desr, memory_order m = memory_order_seq_cst); 19f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral load(memory_order m = memory_order_seq_cst) const volatile; 20f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral load(memory_order m = memory_order_seq_cst) const; 21f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// operator integral() const volatile; 22f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// operator integral() const; 23f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral exchange(integral desr, 24f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order m = memory_order_seq_cst) volatile; 25f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral exchange(integral desr, memory_order m = memory_order_seq_cst); 26f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_weak(integral& expc, integral desr, 27f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order s, memory_order f) volatile; 28f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_weak(integral& expc, integral desr, 29f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order s, memory_order f); 30f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_strong(integral& expc, integral desr, 31f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order s, memory_order f) volatile; 32f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_strong(integral& expc, integral desr, 33f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order s, memory_order f); 34f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_weak(integral& expc, integral desr, 35f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order m = memory_order_seq_cst) volatile; 36f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_weak(integral& expc, integral desr, 37f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order m = memory_order_seq_cst); 38f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_strong(integral& expc, integral desr, 39f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order m = memory_order_seq_cst) volatile; 40f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// bool compare_exchange_strong(integral& expc, integral desr, 41f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// memory_order m = memory_order_seq_cst); 42f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 43f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral 44f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile; 45f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral fetch_add(integral op, memory_order m = memory_order_seq_cst); 46f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral 47f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile; 48f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral fetch_sub(integral op, memory_order m = memory_order_seq_cst); 49f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral 50f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile; 51f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral fetch_and(integral op, memory_order m = memory_order_seq_cst); 52f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral 53f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile; 54f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral fetch_or(integral op, memory_order m = memory_order_seq_cst); 55f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral 56f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile; 57f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral fetch_xor(integral op, memory_order m = memory_order_seq_cst); 58f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 59f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// atomic() = default; 60f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// constexpr atomic(integral desr); 61f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// atomic(const atomic&) = delete; 62f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// atomic& operator=(const atomic&) = delete; 63f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// atomic& operator=(const atomic&) volatile = delete; 64f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator=(integral desr) volatile; 65f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator=(integral desr); 66f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// 67f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator++(int) volatile; 68f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator++(int); 69f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator--(int) volatile; 70f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator--(int); 71f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator++() volatile; 72f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator++(); 73f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator--() volatile; 74f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator--(); 75f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator+=(integral op) volatile; 76f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator+=(integral op); 77f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator-=(integral op) volatile; 78f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator-=(integral op); 79f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator&=(integral op) volatile; 80f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator&=(integral op); 81f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator|=(integral op) volatile; 82f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator|=(integral op); 83f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator^=(integral op) volatile; 84f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// integral operator^=(integral op); 85f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant// }; 86f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 87f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#include <atomic> 8874f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant#include <new> 89f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#include <cassert> 90f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 91f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnanttemplate <class A, class T> 92f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnantvoid 93f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnantdo_test() 94f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant{ 95f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant A obj(T(0)); 96f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(0)); 97f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant std::atomic_init(&obj, T(1)); 98f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 99f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant std::atomic_init(&obj, T(2)); 100f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 101f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant bool b0 = obj.is_lock_free(); 102f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant obj.store(T(0)); 103f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(0)); 104f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant obj.store(T(1), std::memory_order_release); 105f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 106f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.load() == T(1)); 107f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.load(std::memory_order_acquire) == T(1)); 108f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.exchange(T(2)) == T(1)); 109f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 110f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2)); 111f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(3)); 112f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant T x = obj; 113f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.compare_exchange_weak(x, T(2)) == true); 114f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 115f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(x == T(3)); 116f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.compare_exchange_weak(x, T(1)) == false); 117f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 118d3eca759a2ce3125613fb840287c77ee1f372b10David Chisnall assert(x == T(2)); 119f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant x = T(2); 120f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.compare_exchange_strong(x, T(1)) == true); 121f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 122f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(x == T(2)); 123f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj.compare_exchange_strong(x, T(0)) == false); 124f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 125d3eca759a2ce3125613fb840287c77ee1f372b10David Chisnall assert(x == T(1)); 126f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj = T(0)) == T(0)); 127f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(0)); 128f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj++ == T(0)); 129f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 130f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(++obj == T(2)); 131f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 132f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(--obj == T(1)); 133f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(1)); 134f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj-- == T(1)); 135f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(0)); 136f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant obj = T(2); 137f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj += T(3)) == T(5)); 138f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(5)); 139f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj -= T(3)) == T(2)); 140f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(2)); 141f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj |= T(5)) == T(7)); 142f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(7)); 143f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj &= T(0xF)) == T(7)); 144f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(7)); 145f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert((obj ^= T(0xF)) == T(8)); 146f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant assert(obj == T(8)); 14774f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant 14874f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant { 14974f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; 15074f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant A& zero = *new (storage) A(); 15174f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant assert(zero == 0); 15274f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant zero.~A(); 15374f4da7219100afcff4baab33d12910d29eb127eHoward Hinnant } 154f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant} 155f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 156f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnanttemplate <class A, class T> 157f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnantvoid test() 158f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant{ 159f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant do_test<A, T>(); 160f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant do_test<volatile A, T>(); 161f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant} 162f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 163f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 164f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnantint main() 165f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant{ 166f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_char, char>(); 167f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_schar, signed char>(); 168f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_uchar, unsigned char>(); 169f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_short, short>(); 170f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_ushort, unsigned short>(); 171f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_int, int>(); 172f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_uint, unsigned int>(); 173f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_long, long>(); 174f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_ulong, unsigned long>(); 175f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_llong, long long>(); 176f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_ullong, unsigned long long>(); 177f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 178f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_char16_t, char16_t>(); 179f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_char32_t, char32_t>(); 180f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 181f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<std::atomic_wchar_t, wchar_t>(); 182f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant 183f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_char, char>(); 184f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_schar, signed char>(); 185f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_uchar, unsigned char>(); 186f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_short, short>(); 187f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_ushort, unsigned short>(); 188f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_int, int>(); 189f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_uint, unsigned int>(); 190f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_long, long>(); 191f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_ulong, unsigned long>(); 192f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_llong, long long>(); 193f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_ullong, unsigned long long>(); 194f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 195f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_char16_t, char16_t>(); 196f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_char32_t, char32_t>(); 197f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 198f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant test<volatile std::atomic_wchar_t, wchar_t>(); 199f02417b600ee58299effa60b5ffd9d58b8bc3129Howard Hinnant} 200