111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The LLVM Compiler Infrastructure 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Source Licenses. See LICENSE.TXT for details. 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// UNSUPPORTED: libcpp-has-no-threads 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <atomic> 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// template <> 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// struct atomic<integral> 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// { 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool is_lock_free() const volatile; 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool is_lock_free() const; 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// void store(integral desr, memory_order m = memory_order_seq_cst) volatile; 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// void store(integral desr, memory_order m = memory_order_seq_cst); 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral load(memory_order m = memory_order_seq_cst) const volatile; 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral load(memory_order m = memory_order_seq_cst) const; 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// operator integral() const volatile; 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// operator integral() const; 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral exchange(integral desr, 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order m = memory_order_seq_cst) volatile; 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral exchange(integral desr, memory_order m = memory_order_seq_cst); 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_weak(integral& expc, integral desr, 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order s, memory_order f) volatile; 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_weak(integral& expc, integral desr, 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order s, memory_order f); 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_strong(integral& expc, integral desr, 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order s, memory_order f) volatile; 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_strong(integral& expc, integral desr, 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order s, memory_order f); 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_weak(integral& expc, integral desr, 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order m = memory_order_seq_cst) volatile; 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_weak(integral& expc, integral desr, 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order m = memory_order_seq_cst); 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_strong(integral& expc, integral desr, 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order m = memory_order_seq_cst) volatile; 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// bool compare_exchange_strong(integral& expc, integral desr, 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// memory_order m = memory_order_seq_cst); 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile; 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral fetch_add(integral op, memory_order m = memory_order_seq_cst); 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile; 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral fetch_sub(integral op, memory_order m = memory_order_seq_cst); 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile; 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral fetch_and(integral op, memory_order m = memory_order_seq_cst); 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile; 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral fetch_or(integral op, memory_order m = memory_order_seq_cst); 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile; 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral fetch_xor(integral op, memory_order m = memory_order_seq_cst); 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// atomic() = default; 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// constexpr atomic(integral desr); 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// atomic(const atomic&) = delete; 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// atomic& operator=(const atomic&) = delete; 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// atomic& operator=(const atomic&) volatile = delete; 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator=(integral desr) volatile; 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator=(integral desr); 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator++(int) volatile; 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator++(int); 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator--(int) volatile; 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator--(int); 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator++() volatile; 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator++(); 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator--() volatile; 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator--(); 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator+=(integral op) volatile; 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator+=(integral op); 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator-=(integral op) volatile; 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator-=(integral op); 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator&=(integral op) volatile; 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator&=(integral op); 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator|=(integral op) volatile; 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator|=(integral op); 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator^=(integral op) volatile; 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// integral operator^=(integral op); 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// }; 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <atomic> 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <new> 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cassert> 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cmpxchg_loop.h> 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class A, class T> 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdo_test() 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert A obj(T(0)); 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(0)); 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::atomic_init(&obj, T(1)); 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::atomic_init(&obj, T(2)); 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool b0 = obj.is_lock_free(); 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((void)b0); // mark as unused 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj.store(T(0)); 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(0)); 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj.store(T(1), std::memory_order_release); 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.load() == T(1)); 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.load(std::memory_order_acquire) == T(1)); 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.exchange(T(2)) == T(1)); 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2)); 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(3)); 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert T x = obj; 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(cmpxchg_weak_loop(obj, x, T(2)) == true); 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(x == T(3)); 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.compare_exchange_weak(x, T(1)) == false); 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(x == T(2)); 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert x = T(2); 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.compare_exchange_strong(x, T(1)) == true); 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(x == T(2)); 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj.compare_exchange_strong(x, T(0)) == false); 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(x == T(1)); 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj = T(0)) == T(0)); 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(0)); 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj++ == T(0)); 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(++obj == T(2)); 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(--obj == T(1)); 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(1)); 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj-- == T(1)); 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(0)); 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj = T(2); 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj += T(3)) == T(5)); 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(5)); 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj -= T(3)) == T(2)); 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(2)); 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj |= T(5)) == T(7)); 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(7)); 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj &= T(0xF)) == T(7)); 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(7)); 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert((obj ^= T(0xF)) == T(8)); 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(obj == T(8)); 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert A& zero = *new (storage) A(); 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(zero == 0); 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert zero.~A(); 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class A, class T> 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid test() 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert do_test<A, T>(); 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert do_test<volatile A, T>(); 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint main() 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_char, char>(); 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_schar, signed char>(); 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_uchar, unsigned char>(); 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_short, short>(); 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_ushort, unsigned short>(); 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_int, int>(); 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_uint, unsigned int>(); 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_long, long>(); 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_ulong, unsigned long>(); 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_llong, long long>(); 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_ullong, unsigned long long>(); 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_char16_t, char16_t>(); 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_char32_t, char32_t>(); 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<std::atomic_wchar_t, wchar_t>(); 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_char, char>(); 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_schar, signed char>(); 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_uchar, unsigned char>(); 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_short, short>(); 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_ushort, unsigned short>(); 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_int, int>(); 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_uint, unsigned int>(); 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_long, long>(); 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_ulong, unsigned long>(); 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_llong, long long>(); 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_ullong, unsigned long long>(); 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_char16_t, char16_t>(); 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_char32_t, char32_t>(); 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _LIBCPP_HAS_NO_UNICODE_CHARS 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test<volatile std::atomic_wchar_t, wchar_t>(); 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 205