1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef ATOMIC_HELPERS_H 10 #define ATOMIC_HELPERS_H 11 12 #include <cassert> 13 #include <cstdint> 14 15 #include "test_macros.h" 16 17 struct UserAtomicType { 18 int i; 19 iUserAtomicType20 explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} 21 22 friend bool operator==(const UserAtomicType& x, const UserAtomicType& y) { return x.i == y.i; } 23 }; 24 25 /* 26 27 Enable these once we have P0528 28 29 struct WeirdUserAtomicType 30 { 31 char i, j, k; // the 3 chars of doom 32 33 explicit WeirdUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} 34 35 friend bool operator==(const WeirdUserAtomicType& x, const WeirdUserAtomicType& y) 36 { return x.i == y.i; } 37 }; 38 39 struct PaddedUserAtomicType 40 { 41 char i; int j; // probably lock-free? 42 43 explicit PaddedUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} 44 45 friend bool operator==(const PaddedUserAtomicType& x, const PaddedUserAtomicType& y) 46 { return x.i == y.i; } 47 }; 48 49 */ 50 51 struct LargeUserAtomicType { 52 int a[128]; /* decidedly not lock-free */ 53 54 LargeUserAtomicType(int d = 0) TEST_NOEXCEPT { 55 for (auto&& e : a) 56 e = d++; 57 } 58 59 friend bool operator==(LargeUserAtomicType const& x, LargeUserAtomicType const& y) TEST_NOEXCEPT { 60 for (int i = 0; i < 128; ++i) 61 if (x.a[i] != y.a[i]) 62 return false; 63 return true; 64 } 65 }; 66 67 template <template <class TestArg> class TestFunctor> 68 struct TestEachIntegralType { operatorTestEachIntegralType69 void operator()() const { 70 TestFunctor<char>()(); 71 TestFunctor<signed char>()(); 72 TestFunctor<unsigned char>()(); 73 TestFunctor<short>()(); 74 TestFunctor<unsigned short>()(); 75 TestFunctor<int>()(); 76 TestFunctor<unsigned int>()(); 77 TestFunctor<long>()(); 78 TestFunctor<unsigned long>()(); 79 TestFunctor<long long>()(); 80 TestFunctor<unsigned long long>()(); 81 TestFunctor<wchar_t>()(); 82 #if TEST_STD_VER > 17 && defined(__cpp_char8_t) 83 TestFunctor<char8_t>()(); 84 #endif 85 TestFunctor<char16_t>()(); 86 TestFunctor<char32_t>()(); 87 TestFunctor<std::int8_t>()(); 88 TestFunctor<std::uint8_t>()(); 89 TestFunctor<std::int16_t>()(); 90 TestFunctor<std::uint16_t>()(); 91 TestFunctor<std::int32_t>()(); 92 TestFunctor<std::uint32_t>()(); 93 TestFunctor<std::int64_t>()(); 94 TestFunctor<std::uint64_t>()(); 95 } 96 }; 97 98 template <template <class TestArg> class TestFunctor> 99 struct TestEachFloatingPointType { operatorTestEachFloatingPointType100 void operator()() const { 101 TestFunctor<float>()(); 102 TestFunctor<double>()(); 103 TestFunctor<long double>()(); 104 } 105 }; 106 107 template <template <class TestArg> class TestFunctor> 108 struct TestEachPointerType { operatorTestEachPointerType109 void operator()() const { 110 TestFunctor<int*>()(); 111 TestFunctor<const int*>()(); 112 } 113 }; 114 115 template <template <class TestArg> class TestFunctor> 116 struct TestEachAtomicType { operatorTestEachAtomicType117 void operator()() const { 118 TestEachIntegralType<TestFunctor>()(); 119 TestFunctor<UserAtomicType>()(); 120 /* 121 Note: These aren't going to be lock-free, 122 so some libatomic.a is necessary. To handle 123 the case where the support functions are 124 missing, all tests that use this file should add: 125 XFAIL: !non-lockfree-atomics 126 */ 127 TestFunctor<LargeUserAtomicType>()(); 128 /* 129 Enable these once we have P0528 130 131 TestFunctor<PaddedUserAtomicType>()(); 132 TestFunctor<WeirdUserAtomicType>()(); 133 */ 134 TestFunctor<int*>()(); 135 TestFunctor<const int*>()(); 136 TestFunctor<float>()(); 137 TestFunctor<double>()(); 138 } 139 }; 140 141 #endif // ATOMIC_HELPERS_H 142