1 | // Copyright (C) 2011 Thiago Macieira <thiago@kde.org> |
---|---|
2 | // Copyright (C) 2018 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QBASICATOMIC_H |
6 | #define QBASICATOMIC_H |
7 | |
8 | #include <QtCore/qatomic_cxx11.h> |
9 | |
10 | QT_WARNING_PUSH |
11 | QT_WARNING_DISABLE_MSVC(4522) |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | #if 0 |
16 | // silence syncqt warnings |
17 | QT_END_NAMESPACE |
18 | #pragma qt_no_master_include |
19 | #pragma qt_sync_stop_processing |
20 | #endif |
21 | |
22 | template <typename T> |
23 | class QBasicAtomicInteger |
24 | { |
25 | public: |
26 | typedef T Type; |
27 | typedef QAtomicOps<T> Ops; |
28 | // static check that this is a valid integer |
29 | static_assert(std::is_integral_v<T>, "template parameter is not an integral type"); |
30 | static_assert(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform"); |
31 | |
32 | typename Ops::Type _q_value; |
33 | |
34 | // Everything below is either implemented in ../arch/qatomic_XXX.h or (as |
35 | // fallback) in qgenericatomic.h |
36 | T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); } |
37 | void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); } |
38 | |
39 | T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); } |
40 | void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); } |
41 | operator T() const noexcept { return loadAcquire(); } |
42 | T operator=(T newValue) noexcept { storeRelease(newValue); return newValue; } |
43 | |
44 | static constexpr bool isReferenceCountingNative() noexcept { return Ops::isReferenceCountingNative(); } |
45 | static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); } |
46 | |
47 | bool ref() noexcept { return Ops::ref(_q_value); } |
48 | bool deref() noexcept { return Ops::deref(_q_value); } |
49 | |
50 | static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); } |
51 | static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); } |
52 | |
53 | bool testAndSetRelaxed(T expectedValue, T newValue) noexcept |
54 | { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); } |
55 | bool testAndSetAcquire(T expectedValue, T newValue) noexcept |
56 | { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); } |
57 | bool testAndSetRelease(T expectedValue, T newValue) noexcept |
58 | { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); } |
59 | bool testAndSetOrdered(T expectedValue, T newValue) noexcept |
60 | { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); } |
61 | |
62 | bool testAndSetRelaxed(T expectedValue, T newValue, T ¤tValue) noexcept |
63 | { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, ¤tValue); } |
64 | bool testAndSetAcquire(T expectedValue, T newValue, T ¤tValue) noexcept |
65 | { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, ¤tValue); } |
66 | bool testAndSetRelease(T expectedValue, T newValue, T ¤tValue) noexcept |
67 | { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, ¤tValue); } |
68 | bool testAndSetOrdered(T expectedValue, T newValue, T ¤tValue) noexcept |
69 | { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, ¤tValue); } |
70 | |
71 | static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); } |
72 | static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); } |
73 | |
74 | T fetchAndStoreRelaxed(T newValue) noexcept |
75 | { return Ops::fetchAndStoreRelaxed(_q_value, newValue); } |
76 | T fetchAndStoreAcquire(T newValue) noexcept |
77 | { return Ops::fetchAndStoreAcquire(_q_value, newValue); } |
78 | T fetchAndStoreRelease(T newValue) noexcept |
79 | { return Ops::fetchAndStoreRelease(_q_value, newValue); } |
80 | T fetchAndStoreOrdered(T newValue) noexcept |
81 | { return Ops::fetchAndStoreOrdered(_q_value, newValue); } |
82 | |
83 | static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); } |
84 | static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); } |
85 | |
86 | T fetchAndAddRelaxed(T valueToAdd) noexcept |
87 | { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); } |
88 | T fetchAndAddAcquire(T valueToAdd) noexcept |
89 | { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); } |
90 | T fetchAndAddRelease(T valueToAdd) noexcept |
91 | { return Ops::fetchAndAddRelease(_q_value, valueToAdd); } |
92 | T fetchAndAddOrdered(T valueToAdd) noexcept |
93 | { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); } |
94 | |
95 | T fetchAndSubRelaxed(T valueToAdd) noexcept |
96 | { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); } |
97 | T fetchAndSubAcquire(T valueToAdd) noexcept |
98 | { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); } |
99 | T fetchAndSubRelease(T valueToAdd) noexcept |
100 | { return Ops::fetchAndSubRelease(_q_value, valueToAdd); } |
101 | T fetchAndSubOrdered(T valueToAdd) noexcept |
102 | { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); } |
103 | |
104 | T fetchAndAndRelaxed(T valueToAdd) noexcept |
105 | { return Ops::fetchAndAndRelaxed(_q_value, valueToAdd); } |
106 | T fetchAndAndAcquire(T valueToAdd) noexcept |
107 | { return Ops::fetchAndAndAcquire(_q_value, valueToAdd); } |
108 | T fetchAndAndRelease(T valueToAdd) noexcept |
109 | { return Ops::fetchAndAndRelease(_q_value, valueToAdd); } |
110 | T fetchAndAndOrdered(T valueToAdd) noexcept |
111 | { return Ops::fetchAndAndOrdered(_q_value, valueToAdd); } |
112 | |
113 | T fetchAndOrRelaxed(T valueToAdd) noexcept |
114 | { return Ops::fetchAndOrRelaxed(_q_value, valueToAdd); } |
115 | T fetchAndOrAcquire(T valueToAdd) noexcept |
116 | { return Ops::fetchAndOrAcquire(_q_value, valueToAdd); } |
117 | T fetchAndOrRelease(T valueToAdd) noexcept |
118 | { return Ops::fetchAndOrRelease(_q_value, valueToAdd); } |
119 | T fetchAndOrOrdered(T valueToAdd) noexcept |
120 | { return Ops::fetchAndOrOrdered(_q_value, valueToAdd); } |
121 | |
122 | T fetchAndXorRelaxed(T valueToAdd) noexcept |
123 | { return Ops::fetchAndXorRelaxed(_q_value, valueToAdd); } |
124 | T fetchAndXorAcquire(T valueToAdd) noexcept |
125 | { return Ops::fetchAndXorAcquire(_q_value, valueToAdd); } |
126 | T fetchAndXorRelease(T valueToAdd) noexcept |
127 | { return Ops::fetchAndXorRelease(_q_value, valueToAdd); } |
128 | T fetchAndXorOrdered(T valueToAdd) noexcept |
129 | { return Ops::fetchAndXorOrdered(_q_value, valueToAdd); } |
130 | |
131 | T operator++() noexcept |
132 | { return fetchAndAddOrdered(valueToAdd: 1) + 1; } |
133 | T operator++(int) noexcept |
134 | { return fetchAndAddOrdered(valueToAdd: 1); } |
135 | T operator--() noexcept |
136 | { return fetchAndSubOrdered(valueToAdd: 1) - 1; } |
137 | T operator--(int) noexcept |
138 | { return fetchAndSubOrdered(valueToAdd: 1); } |
139 | |
140 | T operator+=(T v) noexcept |
141 | { return fetchAndAddOrdered(valueToAdd: v) + v; } |
142 | T operator-=(T v) noexcept |
143 | { return fetchAndSubOrdered(valueToAdd: v) - v; } |
144 | T operator&=(T v) noexcept |
145 | { return fetchAndAndOrdered(valueToAdd: v) & v; } |
146 | T operator|=(T v) noexcept |
147 | { return fetchAndOrOrdered(valueToAdd: v) | v; } |
148 | T operator^=(T v) noexcept |
149 | { return fetchAndXorOrdered(valueToAdd: v) ^ v; } |
150 | |
151 | |
152 | QBasicAtomicInteger() = default; |
153 | constexpr QBasicAtomicInteger(T value) noexcept : _q_value(value) {} |
154 | QBasicAtomicInteger(const QBasicAtomicInteger &) = delete; |
155 | QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete; |
156 | QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete; |
157 | }; |
158 | typedef QBasicAtomicInteger<int> QBasicAtomicInt; |
159 | |
160 | template <typename X> |
161 | class QBasicAtomicPointer |
162 | { |
163 | public: |
164 | typedef X *Type; |
165 | typedef QAtomicOps<Type> Ops; |
166 | typedef typename Ops::Type AtomicType; |
167 | |
168 | AtomicType _q_value; |
169 | |
170 | Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); } |
171 | void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); } |
172 | |
173 | operator Type() const noexcept { return loadAcquire(); } |
174 | Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; } |
175 | |
176 | // Atomic API, implemented in qatomic_XXX.h |
177 | Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); } |
178 | void storeRelease(Type newValue) noexcept { Ops::storeRelease(_q_value, newValue); } |
179 | |
180 | static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); } |
181 | static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); } |
182 | |
183 | bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept |
184 | { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); } |
185 | bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept |
186 | { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); } |
187 | bool testAndSetRelease(Type expectedValue, Type newValue) noexcept |
188 | { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); } |
189 | bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept |
190 | { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); } |
191 | |
192 | bool testAndSetRelaxed(Type expectedValue, Type newValue, Type ¤tValue) noexcept |
193 | { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, ¤tValue); } |
194 | bool testAndSetAcquire(Type expectedValue, Type newValue, Type ¤tValue) noexcept |
195 | { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, ¤tValue); } |
196 | bool testAndSetRelease(Type expectedValue, Type newValue, Type ¤tValue) noexcept |
197 | { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, ¤tValue); } |
198 | bool testAndSetOrdered(Type expectedValue, Type newValue, Type ¤tValue) noexcept |
199 | { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, ¤tValue); } |
200 | |
201 | static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); } |
202 | static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); } |
203 | |
204 | Type fetchAndStoreRelaxed(Type newValue) noexcept |
205 | { return Ops::fetchAndStoreRelaxed(_q_value, newValue); } |
206 | Type fetchAndStoreAcquire(Type newValue) noexcept |
207 | { return Ops::fetchAndStoreAcquire(_q_value, newValue); } |
208 | Type fetchAndStoreRelease(Type newValue) noexcept |
209 | { return Ops::fetchAndStoreRelease(_q_value, newValue); } |
210 | Type fetchAndStoreOrdered(Type newValue) noexcept |
211 | { return Ops::fetchAndStoreOrdered(_q_value, newValue); } |
212 | |
213 | static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); } |
214 | static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); } |
215 | |
216 | Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept |
217 | { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); } |
218 | Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept |
219 | { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); } |
220 | Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept |
221 | { return Ops::fetchAndAddRelease(_q_value, valueToAdd); } |
222 | Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept |
223 | { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); } |
224 | |
225 | Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept |
226 | { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); } |
227 | Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept |
228 | { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); } |
229 | Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept |
230 | { return Ops::fetchAndSubRelease(_q_value, valueToAdd); } |
231 | Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept |
232 | { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); } |
233 | |
234 | Type operator++() noexcept |
235 | { return fetchAndAddOrdered(valueToAdd: 1) + 1; } |
236 | Type operator++(int) noexcept |
237 | { return fetchAndAddOrdered(valueToAdd: 1); } |
238 | Type operator--() noexcept |
239 | { return fetchAndSubOrdered(valueToAdd: 1) - 1; } |
240 | Type operator--(int) noexcept |
241 | { return fetchAndSubOrdered(valueToAdd: 1); } |
242 | Type operator+=(qptrdiff valueToAdd) noexcept |
243 | { return fetchAndAddOrdered(valueToAdd) + valueToAdd; } |
244 | Type operator-=(qptrdiff valueToSub) noexcept |
245 | { return fetchAndSubOrdered(valueToAdd: valueToSub) - valueToSub; } |
246 | |
247 | QBasicAtomicPointer() = default; |
248 | constexpr QBasicAtomicPointer(Type value) noexcept : _q_value(value) {} |
249 | QBasicAtomicPointer(const QBasicAtomicPointer &) = delete; |
250 | QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) = delete; |
251 | QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) volatile = delete; |
252 | }; |
253 | |
254 | #ifndef Q_BASIC_ATOMIC_INITIALIZER |
255 | # define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) } |
256 | #endif |
257 | |
258 | QT_END_NAMESPACE |
259 | |
260 | QT_WARNING_POP |
261 | |
262 | #endif // QBASICATOMIC_H |
263 |
Definitions
- QBasicAtomicInteger
- loadRelaxed
- storeRelaxed
- loadAcquire
- storeRelease
- operator T
- operator=
- isReferenceCountingNative
- isReferenceCountingWaitFree
- ref
- deref
- isTestAndSetNative
- isTestAndSetWaitFree
- testAndSetRelaxed
- testAndSetAcquire
- testAndSetRelease
- testAndSetOrdered
- testAndSetRelaxed
- testAndSetAcquire
- testAndSetRelease
- testAndSetOrdered
- isFetchAndStoreNative
- isFetchAndStoreWaitFree
- fetchAndStoreRelaxed
- fetchAndStoreAcquire
- fetchAndStoreRelease
- fetchAndStoreOrdered
- isFetchAndAddNative
- isFetchAndAddWaitFree
- fetchAndAddRelaxed
- fetchAndAddAcquire
- fetchAndAddRelease
- fetchAndAddOrdered
- fetchAndSubRelaxed
- fetchAndSubAcquire
- fetchAndSubRelease
- fetchAndSubOrdered
- fetchAndAndRelaxed
- fetchAndAndAcquire
- fetchAndAndRelease
- fetchAndAndOrdered
- fetchAndOrRelaxed
- fetchAndOrAcquire
- fetchAndOrRelease
- fetchAndOrOrdered
- fetchAndXorRelaxed
- fetchAndXorAcquire
- fetchAndXorRelease
- fetchAndXorOrdered
- operator++
- operator++
- operator--
- operator--
- operator+=
- operator-=
- operator&=
- operator|=
- operator^=
- QBasicAtomicInteger
- QBasicAtomicInteger
- QBasicAtomicInteger
- operator=
- operator=
- QBasicAtomicPointer
- loadRelaxed
- storeRelaxed
- operator Type
- operator=
- loadAcquire
- storeRelease
- isTestAndSetNative
- isTestAndSetWaitFree
- testAndSetRelaxed
- testAndSetAcquire
- testAndSetRelease
- testAndSetOrdered
- testAndSetRelaxed
- testAndSetAcquire
- testAndSetRelease
- testAndSetOrdered
- isFetchAndStoreNative
- isFetchAndStoreWaitFree
- fetchAndStoreRelaxed
- fetchAndStoreAcquire
- fetchAndStoreRelease
- fetchAndStoreOrdered
- isFetchAndAddNative
- isFetchAndAddWaitFree
- fetchAndAddRelaxed
- fetchAndAddAcquire
- fetchAndAddRelease
- fetchAndAddOrdered
- fetchAndSubRelaxed
- fetchAndSubAcquire
- fetchAndSubRelease
- fetchAndSubOrdered
- operator++
- operator++
- operator--
- operator--
- operator+=
- operator-=
- QBasicAtomicPointer
- QBasicAtomicPointer
- QBasicAtomicPointer
- operator=
Learn to use CMake with our Intro Training
Find out more