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