• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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