]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
Vendor import of libc++ trunk r351319 (just before the release_80
[FreeBSD/FreeBSD.git] / test / std / atomics / atomics.lockfree / isalwayslockfree.pass.cpp
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, c++98, c++03, c++11, c++14
11
12 // <atomic>
13
14 // static constexpr bool is_always_lock_free;
15
16 #include <atomic>
17 #include <cassert>
18
19 #if !defined(__cpp_lib_atomic_is_always_lock_free)
20 # error Feature test macro missing.
21 #endif
22
23 template <typename T> void checkAlwaysLockFree() {
24   if (std::atomic<T>::is_always_lock_free)
25     assert(std::atomic<T>().is_lock_free());
26 }
27
28 // FIXME: This separate test is needed to work around llvm.org/PR31864
29 // which causes ATOMIC_LLONG_LOCK_FREE to be defined as '1' in 32-bit builds
30 // even though __atomic_always_lock_free returns true for the same type.
31 constexpr bool NeedWorkaroundForPR31864 =
32 #if defined(__clang__)
33 (sizeof(void*) == 4); // Needed on 32 bit builds
34 #else
35 false;
36 #endif
37
38 template <bool Disable = NeedWorkaroundForPR31864,
39   std::enable_if_t<!Disable>* = nullptr,
40   class LLong = long long,
41   class ULLong = unsigned long long>
42 void checkLongLongTypes() {
43   static_assert(std::atomic<LLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
44   static_assert(std::atomic<ULLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
45 }
46
47 // Used to make the calls to __atomic_always_lock_free dependent on a template
48 // parameter.
49 template <class T> constexpr size_t getSizeOf() { return sizeof(T); }
50
51 template <bool Enable = NeedWorkaroundForPR31864,
52   std::enable_if_t<Enable>* = nullptr,
53   class LLong = long long,
54   class ULLong = unsigned long long>
55 void checkLongLongTypes() {
56   constexpr bool ExpectLockFree = __atomic_always_lock_free(getSizeOf<LLong>(), 0);
57   static_assert(std::atomic<LLong>::is_always_lock_free == ExpectLockFree, "");
58   static_assert(std::atomic<ULLong>::is_always_lock_free == ExpectLockFree, "");
59   static_assert((0 != ATOMIC_LLONG_LOCK_FREE) == ExpectLockFree, "");
60 }
61
62 void run()
63 {
64 // structs and unions can't be defined in the template invocation.
65 // Work around this with a typedef.
66 #define CHECK_ALWAYS_LOCK_FREE(T)                                              \
67   do {                                                                         \
68     typedef T type;                                                            \
69     checkAlwaysLockFree<type>();                                               \
70   } while (0)
71
72     CHECK_ALWAYS_LOCK_FREE(bool);
73     CHECK_ALWAYS_LOCK_FREE(char);
74     CHECK_ALWAYS_LOCK_FREE(signed char);
75     CHECK_ALWAYS_LOCK_FREE(unsigned char);
76     CHECK_ALWAYS_LOCK_FREE(char16_t);
77     CHECK_ALWAYS_LOCK_FREE(char32_t);
78     CHECK_ALWAYS_LOCK_FREE(wchar_t);
79     CHECK_ALWAYS_LOCK_FREE(short);
80     CHECK_ALWAYS_LOCK_FREE(unsigned short);
81     CHECK_ALWAYS_LOCK_FREE(int);
82     CHECK_ALWAYS_LOCK_FREE(unsigned int);
83     CHECK_ALWAYS_LOCK_FREE(long);
84     CHECK_ALWAYS_LOCK_FREE(unsigned long);
85     CHECK_ALWAYS_LOCK_FREE(long long);
86     CHECK_ALWAYS_LOCK_FREE(unsigned long long);
87     CHECK_ALWAYS_LOCK_FREE(std::nullptr_t);
88     CHECK_ALWAYS_LOCK_FREE(void*);
89     CHECK_ALWAYS_LOCK_FREE(float);
90     CHECK_ALWAYS_LOCK_FREE(double);
91     CHECK_ALWAYS_LOCK_FREE(long double);
92 #if __has_attribute(vector_size) && defined(_LIBCPP_VERSION)
93     CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(1 * sizeof(int)))));
94     CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(2 * sizeof(int)))));
95     CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(4 * sizeof(int)))));
96     CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(16 * sizeof(int)))));
97     CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(32 * sizeof(int)))));
98     CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(1 * sizeof(float)))));
99     CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(2 * sizeof(float)))));
100     CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(4 * sizeof(float)))));
101     CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(16 * sizeof(float)))));
102     CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(32 * sizeof(float)))));
103     CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(1 * sizeof(double)))));
104     CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(2 * sizeof(double)))));
105     CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(4 * sizeof(double)))));
106     CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(16 * sizeof(double)))));
107     CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(32 * sizeof(double)))));
108 #endif // __has_attribute(vector_size) && defined(_LIBCPP_VERSION)
109     CHECK_ALWAYS_LOCK_FREE(struct Empty {});
110     CHECK_ALWAYS_LOCK_FREE(struct OneInt { int i; });
111     CHECK_ALWAYS_LOCK_FREE(struct IntArr2 { int i[2]; });
112     CHECK_ALWAYS_LOCK_FREE(struct LLIArr2 { long long int i[2]; });
113     CHECK_ALWAYS_LOCK_FREE(struct LLIArr4 { long long int i[4]; });
114     CHECK_ALWAYS_LOCK_FREE(struct LLIArr8 { long long int i[8]; });
115     CHECK_ALWAYS_LOCK_FREE(struct LLIArr16 { long long int i[16]; });
116     CHECK_ALWAYS_LOCK_FREE(struct Padding { char c; /* padding */ long long int i; });
117     CHECK_ALWAYS_LOCK_FREE(union IntFloat { int i; float f; });
118
119     // C macro and static constexpr must be consistent.
120     static_assert(std::atomic<bool>::is_always_lock_free == (2 == ATOMIC_BOOL_LOCK_FREE));
121     static_assert(std::atomic<char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE));
122     static_assert(std::atomic<signed char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE));
123     static_assert(std::atomic<unsigned char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE));
124     static_assert(std::atomic<char16_t>::is_always_lock_free == (2 == ATOMIC_CHAR16_T_LOCK_FREE));
125     static_assert(std::atomic<char32_t>::is_always_lock_free == (2 == ATOMIC_CHAR32_T_LOCK_FREE));
126     static_assert(std::atomic<wchar_t>::is_always_lock_free == (2 == ATOMIC_WCHAR_T_LOCK_FREE));
127     static_assert(std::atomic<short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE));
128     static_assert(std::atomic<unsigned short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE));
129     static_assert(std::atomic<int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE));
130     static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE));
131     static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
132     static_assert(std::atomic<unsigned long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
133     checkLongLongTypes();
134     static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
135     static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
136 }
137
138 int main() { run(); }