Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qbasicatomic.h
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
5
6#ifndef QBASICATOMIC_H
7#define QBASICATOMIC_H
8
9#include <QtCore/qatomic_cxx11.h>
10
11QT_WARNING_PUSH
12QT_WARNING_DISABLE_MSVC(4522)
13
14QT_BEGIN_NAMESPACE
15
16#if 0
17// silence syncqt warnings
18QT_END_NAMESPACE
19#pragma qt_no_master_include
20#pragma qt_sync_stop_processing
21#endif
22
23template <typename T>
24class QBasicAtomicInteger
25{
26 // atomic operations must never cause UB, so do signed add/sub in unsigned space:
27 static T add_no_UB(T lhs, T rhs)
28 {
29 using U = std::make_unsigned_t<T>;
30 return T(U(lhs) + U(rhs));
31 }
32 static T sub_no_UB(T lhs, T rhs)
33 {
34 using U = std::make_unsigned_t<T>;
35 return T(U(lhs) - U(rhs));
36 }
37public:
38 typedef T Type;
39 typedef QAtomicOps<T> Ops;
40 // static check that this is a valid integer
41 static_assert(std::is_integral_v<T>, "template parameter is not an integral type");
42 static_assert(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
43
44 typename Ops::Type _q_value;
45
46 // Everything below is either implemented in ../arch/qatomic_XXX.h or (as
47 // fallback) in qgenericatomic.h
48 T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
49 void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
50
51 T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
52 void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
53 operator T() const noexcept { return loadAcquire(); }
54 T operator=(T newValue) noexcept { storeRelease(newValue); return newValue; }
55
56 static constexpr bool isReferenceCountingNative() noexcept { return Ops::isReferenceCountingNative(); }
57 static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); }
58
59 bool ref() noexcept { return Ops::ref(_q_value); }
60 void refRelaxed() noexcept { Ops::fetchAndAddRelaxed(_q_value, 1); }
61 bool deref() noexcept { return Ops::deref(_q_value); }
62
63 static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
64 static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
65
66 bool testAndSetRelaxed(T expectedValue, T newValue) noexcept
67 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
68 bool testAndSetAcquire(T expectedValue, T newValue) noexcept
69 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
70 bool testAndSetRelease(T expectedValue, T newValue) noexcept
71 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
72 bool testAndSetOrdered(T expectedValue, T newValue) noexcept
73 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
74
75 bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue) noexcept
76 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
77 bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue) noexcept
78 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
79 bool testAndSetRelease(T expectedValue, T newValue, T &currentValue) noexcept
80 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
81 bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue) noexcept
82 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
83
84 static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
85 static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
86
87 T fetchAndStoreRelaxed(T newValue) noexcept
88 { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
89 T fetchAndStoreAcquire(T newValue) noexcept
90 { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
91 T fetchAndStoreRelease(T newValue) noexcept
92 { return Ops::fetchAndStoreRelease(_q_value, newValue); }
93 T fetchAndStoreOrdered(T newValue) noexcept
94 { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
95
96 static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
97 static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
98
99 T fetchAndAddRelaxed(T valueToAdd) noexcept
100 { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
101 T fetchAndAddAcquire(T valueToAdd) noexcept
102 { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
103 T fetchAndAddRelease(T valueToAdd) noexcept
104 { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
105 T fetchAndAddOrdered(T valueToAdd) noexcept
106 { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
107
108 T fetchAndSubRelaxed(T valueToAdd) noexcept
109 { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
110 T fetchAndSubAcquire(T valueToAdd) noexcept
111 { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
112 T fetchAndSubRelease(T valueToAdd) noexcept
113 { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
114 T fetchAndSubOrdered(T valueToAdd) noexcept
115 { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
116
117 T fetchAndAndRelaxed(T valueToAdd) noexcept
118 { return Ops::fetchAndAndRelaxed(_q_value, valueToAdd); }
119 T fetchAndAndAcquire(T valueToAdd) noexcept
120 { return Ops::fetchAndAndAcquire(_q_value, valueToAdd); }
121 T fetchAndAndRelease(T valueToAdd) noexcept
122 { return Ops::fetchAndAndRelease(_q_value, valueToAdd); }
123 T fetchAndAndOrdered(T valueToAdd) noexcept
124 { return Ops::fetchAndAndOrdered(_q_value, valueToAdd); }
125
126 T fetchAndOrRelaxed(T valueToAdd) noexcept
127 { return Ops::fetchAndOrRelaxed(_q_value, valueToAdd); }
128 T fetchAndOrAcquire(T valueToAdd) noexcept
129 { return Ops::fetchAndOrAcquire(_q_value, valueToAdd); }
130 T fetchAndOrRelease(T valueToAdd) noexcept
131 { return Ops::fetchAndOrRelease(_q_value, valueToAdd); }
132 T fetchAndOrOrdered(T valueToAdd) noexcept
133 { return Ops::fetchAndOrOrdered(_q_value, valueToAdd); }
134
135 T fetchAndXorRelaxed(T valueToAdd) noexcept
136 { return Ops::fetchAndXorRelaxed(_q_value, valueToAdd); }
137 T fetchAndXorAcquire(T valueToAdd) noexcept
138 { return Ops::fetchAndXorAcquire(_q_value, valueToAdd); }
139 T fetchAndXorRelease(T valueToAdd) noexcept
140 { return Ops::fetchAndXorRelease(_q_value, valueToAdd); }
141 T fetchAndXorOrdered(T valueToAdd) noexcept
142 { return Ops::fetchAndXorOrdered(_q_value, valueToAdd); }
143
144 T operator++() noexcept
145 { return add_no_UB(fetchAndAddOrdered(1), 1); }
146 T operator++(int) noexcept
147 { return fetchAndAddOrdered(1); }
148 T operator--() noexcept
149 { return sub_no_UB(fetchAndSubOrdered(1), 1); }
150 T operator--(int) noexcept
151 { return fetchAndSubOrdered(1); }
152
153 T operator+=(T v) noexcept
154 { return add_no_UB(fetchAndAddOrdered(v), v); }
155 T operator-=(T v) noexcept
156 { return sub_no_UB(fetchAndSubOrdered(v), v); }
157 T operator&=(T v) noexcept
158 { return fetchAndAndOrdered(v) & v; }
159 T operator|=(T v) noexcept
160 { return fetchAndOrOrdered(v) | v; }
161 T operator^=(T v) noexcept
162 { return fetchAndXorOrdered(v) ^ v; }
163
164
165 QBasicAtomicInteger() = default;
166 constexpr QBasicAtomicInteger(T value) noexcept : _q_value(value) {}
167 QBasicAtomicInteger(const QBasicAtomicInteger &) = delete;
168 QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete;
169 QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete;
170};
172
173template <typename X>
175{
176public:
177 typedef X *Type;
179 typedef typename Ops::Type AtomicType;
180
182
183 Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
184 void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
185
186 operator Type() const noexcept { return loadAcquire(); }
187 Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; }
188
189 // Atomic API, implemented in qatomic_XXX.h
190 Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
191 void storeRelease(Type newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
192
193 static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
194 static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
195
196 bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept
197 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
198 bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept
199 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
200 bool testAndSetRelease(Type expectedValue, Type newValue) noexcept
201 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
202 bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept
203 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
204
205 bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) noexcept
206 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
207 bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) noexcept
208 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
209 bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) noexcept
210 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
211 bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) noexcept
212 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
213
214 static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
215 static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
216
217 Type fetchAndStoreRelaxed(Type newValue) noexcept
218 { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
219 Type fetchAndStoreAcquire(Type newValue) noexcept
220 { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
221 Type fetchAndStoreRelease(Type newValue) noexcept
222 { return Ops::fetchAndStoreRelease(_q_value, newValue); }
223 Type fetchAndStoreOrdered(Type newValue) noexcept
224 { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
225
226 static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
227 static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
228
229 Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept
230 { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
231 Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept
232 { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
233 Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept
234 { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
235 Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept
236 { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
237
238 Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept
239 { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
240 Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept
241 { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
242 Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept
243 { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
244 Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept
245 { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
246
247 Type operator++() noexcept
248 { return fetchAndAddOrdered(1) + 1; }
249 Type operator++(int) noexcept
250 { return fetchAndAddOrdered(1); }
251 Type operator--() noexcept
252 { return fetchAndSubOrdered(1) - 1; }
253 Type operator--(int) noexcept
254 { return fetchAndSubOrdered(1); }
255 Type operator+=(qptrdiff valueToAdd) noexcept
256 { return fetchAndAddOrdered(valueToAdd) + valueToAdd; }
257 Type operator-=(qptrdiff valueToSub) noexcept
258 { return fetchAndSubOrdered(valueToSub) - valueToSub; }
259
261 constexpr QBasicAtomicPointer(Type value) noexcept : _q_value(value) {}
265};
266
267#ifndef Q_BASIC_ATOMIC_INITIALIZER
268# define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }
269#endif
270
271QT_END_NAMESPACE
272
273QT_WARNING_POP
274
275#endif // QBASICATOMIC_H
bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) noexcept
QBasicAtomicPointer & operator=(const QBasicAtomicPointer &)=delete
Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept
bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept
Type fetchAndStoreAcquire(Type newValue) noexcept
Type fetchAndStoreRelease(Type newValue) noexcept
Type operator-=(qptrdiff valueToSub) noexcept
static constexpr bool isFetchAndAddNative() noexcept
bool testAndSetRelease(Type expectedValue, Type newValue) noexcept
Type fetchAndStoreOrdered(Type newValue) noexcept
QBasicAtomicPointer()=default
Type operator=(Type newValue) noexcept
constexpr QBasicAtomicPointer(Type value) noexcept
bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept
bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) noexcept
Type operator++(int) noexcept
QBasicAtomicPointer(const QBasicAtomicPointer &)=delete
Type loadAcquire() const noexcept
QAtomicOps< Type > Ops
Type operator--(int) noexcept
bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) noexcept
Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept
static constexpr bool isFetchAndAddWaitFree() noexcept
bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept
static constexpr bool isTestAndSetNative() noexcept
Type operator+=(qptrdiff valueToAdd) noexcept
Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept
Type loadRelaxed() const noexcept
Type operator++() noexcept
static constexpr bool isFetchAndStoreWaitFree() noexcept
Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept
QBasicAtomicPointer & operator=(const QBasicAtomicPointer &) volatile =delete
void storeRelaxed(Type newValue) noexcept
bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) noexcept
Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept
void storeRelease(Type newValue) noexcept
operator Type() const noexcept
Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept
Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept
static constexpr bool isTestAndSetWaitFree() noexcept
Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept
Type operator--() noexcept
Type fetchAndStoreRelaxed(Type newValue) noexcept
static constexpr bool isFetchAndStoreNative() noexcept
QDeferredDeleteEvent(int loopLevel, int scopeLevel)
Constructs a deferred delete event with the given loop and scope level.
QDisconnectNotifyEvent(int signalIndex)
QBasicAtomicInteger< int > QBasicAtomicInt
static int registerEventTypeZeroBased(int id) noexcept
QBasicAtomicBitField< QEvent::MaxUser - QEvent::User+1 > UserEventTypeRegistry
QT_BEGIN_NAMESPACE Q_TRACE_POINT(qtcore, QEvent_ctor, QEvent *event, QEvent::Type type)
#define Q_IMPL_EVENT_COMMON(Class)
Definition qcoreevent.h:36