1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Copyright (C) 2016 Intel Corporation. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the QtCore module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #include "qatomic.h" |
42 | |
43 | /*! |
44 | \class QAtomicInt |
45 | \inmodule QtCore |
46 | \brief The QAtomicInt class provides platform-independent atomic operations on int. |
47 | \since 4.4 |
48 | |
49 | This class is a equivalent to \c{QAtomicInteger<int>}. All other |
50 | functionality is equivalent. Please see that class for more information. |
51 | |
52 | \sa QAtomicInteger, QAtomicPointer |
53 | */ |
54 | |
55 | /*! |
56 | \class QAtomicInteger |
57 | \inmodule QtCore |
58 | \brief The QAtomicInteger class provides platform-independent atomic operations on integers. |
59 | \ingroup thread |
60 | \since 5.3 |
61 | |
62 | For atomic operations on pointers, see the QAtomicPointer class. |
63 | |
64 | An \e atomic operation is a complex operation that completes without interruption. |
65 | The QAtomicInteger class provides atomic reference counting, test-and-set, fetch-and-store, |
66 | and fetch-and-add for integers. |
67 | |
68 | The template parameter \c T must be a C++ integer type: |
69 | \list |
70 | \li 8-bit: char, signed char, unsigned char, qint8, quint8 |
71 | \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) |
72 | \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) |
73 | \li 64-bit: long long, unsigned long long, qint64, quint64 |
74 | \li platform-specific size: long, unsigned long |
75 | \li pointer size: qintptr, quintptr, qptrdiff |
76 | \endlist |
77 | |
78 | Of the list above, only the 32-bit- and pointer-sized instantiations are guaranteed to |
79 | work on all platforms. Support for other sizes depends on the compiler and |
80 | processor architecture the code is being compiled for. To test whether the |
81 | other types are supported, check the macro \c Q_ATOMIC_INT\e{nn}_IS_SUPPORTED, |
82 | where \c{\e{nn}} is the number of bits desired. |
83 | |
84 | \section1 The Atomic API |
85 | |
86 | \section2 Reference counting |
87 | |
88 | The ref() and deref() functions provide an efficient reference |
89 | counting API. The return value of these functions are used to |
90 | indicate when the last reference has been released. These |
91 | functions allow you to implement your own implicitly shared |
92 | classes. |
93 | |
94 | \snippet code/src_corelib_thread_qatomic.cpp 0 |
95 | |
96 | \section2 Memory ordering |
97 | |
98 | QAtomicInteger provides several implementations of the atomic |
99 | test-and-set, fetch-and-store, and fetch-and-add functions. Each |
100 | implementation defines a memory ordering semantic that describes |
101 | how memory accesses surrounding the atomic instruction are |
102 | executed by the processor. Since many modern architectures allow |
103 | out-of-order execution and memory ordering, using the correct |
104 | semantic is necessary to ensure that your application functions |
105 | properly on all processors. |
106 | |
107 | \list |
108 | |
109 | \li Relaxed - memory ordering is unspecified, leaving the compiler |
110 | and processor to freely reorder memory accesses. |
111 | |
112 | \li Acquire - memory access following the atomic operation (in |
113 | program order) may not be re-ordered before the atomic operation. |
114 | |
115 | \li Release - memory access before the atomic operation (in program |
116 | order) may not be re-ordered after the atomic operation. |
117 | |
118 | \li Ordered - the same Acquire and Release semantics combined. |
119 | |
120 | \endlist |
121 | |
122 | \section2 Test-and-set |
123 | |
124 | If the current value of the QAtomicInteger is an expected value, the |
125 | test-and-set functions assign a new value to the QAtomicInteger and |
126 | return true. If values are \a not the same, these functions do |
127 | nothing and return false. This operation equates to the following |
128 | code: |
129 | |
130 | \snippet code/src_corelib_thread_qatomic.cpp 1 |
131 | |
132 | There are 4 test-and-set functions: testAndSetRelaxed(), |
133 | testAndSetAcquire(), testAndSetRelease(), and |
134 | testAndSetOrdered(). See above for an explanation of the different |
135 | memory ordering semantics. |
136 | |
137 | \section2 Fetch-and-store |
138 | |
139 | The atomic fetch-and-store functions read the current value of the |
140 | QAtomicInteger and then assign a new value, returning the original |
141 | value. This operation equates to the following code: |
142 | |
143 | \snippet code/src_corelib_thread_qatomic.cpp 2 |
144 | |
145 | There are 4 fetch-and-store functions: fetchAndStoreRelaxed(), |
146 | fetchAndStoreAcquire(), fetchAndStoreRelease(), and |
147 | fetchAndStoreOrdered(). See above for an explanation of the |
148 | different memory ordering semantics. |
149 | |
150 | \section2 Fetch-and-add |
151 | |
152 | The atomic fetch-and-add functions read the current value of the |
153 | QAtomicInteger and then add the given value to the current value, |
154 | returning the original value. This operation equates to the |
155 | following code: |
156 | |
157 | \snippet code/src_corelib_thread_qatomic.cpp 3 |
158 | |
159 | There are 4 fetch-and-add functions: fetchAndAddRelaxed(), |
160 | fetchAndAddAcquire(), fetchAndAddRelease(), and |
161 | fetchAndAddOrdered(). See above for an explanation of the |
162 | different memory ordering semantics. |
163 | |
164 | \section1 Feature Tests for the Atomic API |
165 | |
166 | Providing a platform-independent atomic API that works on all |
167 | processors is challenging. The API provided by QAtomicInteger is |
168 | guaranteed to work atomically on all processors. However, since |
169 | not all processors implement support for every operation provided |
170 | by QAtomicInteger, it is necessary to expose information about the |
171 | processor. |
172 | |
173 | You can check at compile time which features are supported on your |
174 | hardware using various macros. These will tell you if your |
175 | hardware always, sometimes, or does not support a particular |
176 | operation. The macros have the form |
177 | Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{nn} is the |
178 | size of the integer (in bits), \e{OPERATION} |
179 | is one of REFERENCE_COUNTING, TEST_AND_SET, |
180 | FETCH_AND_STORE, or FETCH_AND_ADD, and \e{HOW} is one of |
181 | ALWAYS, SOMETIMES, or NOT. There will always be exactly one |
182 | defined macro per operation. For example, if |
183 | Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE is defined, |
184 | neither Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE nor |
185 | Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NOT_NATIVE will be defined. |
186 | |
187 | An operation that completes in constant time is said to be |
188 | wait-free. Such operations are not implemented using locks or |
189 | loops of any kind. For atomic operations that are always |
190 | supported, and that are wait-free, Qt defines the |
191 | Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_WAIT_FREE in addition to the |
192 | Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_ALWAYS_NATIVE. |
193 | |
194 | In cases where an atomic operation is only supported in newer |
195 | generations of the processor, QAtomicInteger also provides a way to |
196 | check at runtime what your hardware supports with the |
197 | isReferenceCountingNative(), isTestAndSetNative(), |
198 | isFetchAndStoreNative(), and isFetchAndAddNative() |
199 | functions. Wait-free implementations can be detected using the |
200 | isReferenceCountingWaitFree(), isTestAndSetWaitFree(), |
201 | isFetchAndStoreWaitFree(), and isFetchAndAddWaitFree() functions. |
202 | |
203 | Below is a complete list of all feature macros for QAtomicInteger: |
204 | |
205 | \list |
206 | |
207 | \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_ALWAYS_NATIVE |
208 | \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE |
209 | \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_NOT_NATIVE |
210 | \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_WAIT_FREE |
211 | |
212 | \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_ALWAYS_NATIVE |
213 | \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_SOMETIMES_NATIVE |
214 | \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_NOT_NATIVE |
215 | \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_WAIT_FREE |
216 | |
217 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_ALWAYS_NATIVE |
218 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_SOMETIMES_NATIVE |
219 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_NOT_NATIVE |
220 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_WAIT_FREE |
221 | |
222 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_ALWAYS_NATIVE |
223 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_SOMETIMES_NATIVE |
224 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_NOT_NATIVE |
225 | \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_WAIT_FREE |
226 | |
227 | \endlist |
228 | |
229 | For compatibility with previous versions of Qt, macros with an empty \e{nn} |
230 | are equivalent to the 32-bit macros. For example, |
231 | Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE is the same as |
232 | Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE. |
233 | |
234 | \sa QAtomicPointer |
235 | */ |
236 | |
237 | /*! |
238 | \fn QAtomicInt::QAtomicInt(int value) |
239 | |
240 | Constructs a QAtomicInt with the given \a value. |
241 | */ |
242 | |
243 | /*! |
244 | \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(T value) |
245 | |
246 | Constructs a QAtomicInteger with the given \a value. |
247 | */ |
248 | |
249 | /*! |
250 | \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(const QAtomicInteger &other) |
251 | |
252 | Constructs a copy of \a other. |
253 | */ |
254 | |
255 | /*! |
256 | \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(const QAtomicInteger &other) |
257 | |
258 | Assigns \a other to this QAtomicInteger and returns a reference to |
259 | this QAtomicInteger. |
260 | */ |
261 | |
262 | |
263 | /*! |
264 | \fn template <typename T> T QAtomicInteger<T>::load() const |
265 | \obsolete |
266 | |
267 | Use loadRelaxed() instead. |
268 | |
269 | Atomically loads the value of this QAtomicInteger using relaxed memory |
270 | ordering. The value is not modified in any way, but note that there's no |
271 | guarantee that it remains so. |
272 | |
273 | \sa storeRelaxed(), loadAcquire() |
274 | */ |
275 | |
276 | /*! |
277 | \fn template <typename T> T QAtomicInteger<T>::loadRelaxed() const |
278 | \since 5.14 |
279 | |
280 | Atomically loads the value of this QAtomicInteger using relaxed memory |
281 | ordering. The value is not modified in any way, but note that there's no |
282 | guarantee that it remains so. |
283 | |
284 | \sa storeRelaxed(), loadAcquire() |
285 | */ |
286 | |
287 | /*! |
288 | \fn template <typename T> T QAtomicInteger<T>::loadAcquire() const |
289 | |
290 | Atomically loads the value of this QAtomicInteger using the "Acquire" memory |
291 | ordering. The value is not modified in any way, but note that there's no |
292 | guarantee that it remains so. |
293 | |
294 | \sa storeRelaxed(), loadRelaxed() |
295 | */ |
296 | |
297 | /*! |
298 | \fn template <typename T> void QAtomicInteger<T>::store(T newValue) |
299 | \obsolete |
300 | |
301 | Use storeRelaxed() instead. |
302 | |
303 | Atomically stores the \a newValue value into this atomic type, using |
304 | relaxed memory ordering. |
305 | |
306 | \sa storeRelease(), loadRelaxed() |
307 | */ |
308 | |
309 | /*! |
310 | \fn template <typename T> void QAtomicInteger<T>::storeRelaxed(T newValue) |
311 | \since 5.14 |
312 | |
313 | Atomically stores the \a newValue value into this atomic type, using |
314 | relaxed memory ordering. |
315 | |
316 | \sa storeRelease(), loadRelaxed() |
317 | */ |
318 | |
319 | /*! |
320 | \fn template <typename T> void QAtomicInteger<T>::storeRelease(T newValue) |
321 | |
322 | Atomically stores the \a newValue value into this atomic type, using |
323 | the "Release" memory ordering. |
324 | |
325 | \sa store(), loadAcquire() |
326 | */ |
327 | |
328 | /*! |
329 | \fn template <typename T> QAtomicInteger<T>::operator T() const |
330 | \since 5.3 |
331 | |
332 | Atomically loads the value of this QAtomicInteger using a sequentially |
333 | consistent memory ordering if possible; or "Acquire" ordering if not. The |
334 | value is not modified in any way, but note that there's no guarantee that |
335 | it remains so. |
336 | |
337 | \sa loadRelaxed(), loadAcquire() |
338 | */ |
339 | |
340 | /*! |
341 | \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(T) |
342 | \since 5.3 |
343 | |
344 | Atomically stores the other value into this atomic type using a |
345 | sequentially consistent memory ordering if possible; or "Release" ordering |
346 | if not. This function returns a reference to this object. |
347 | |
348 | \sa storeRelaxed(), storeRelease() |
349 | */ |
350 | |
351 | /*! |
352 | \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative() |
353 | |
354 | Returns \c true if reference counting is implemented using atomic |
355 | processor instructions, false otherwise. |
356 | */ |
357 | |
358 | /*! |
359 | \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingWaitFree() |
360 | |
361 | Returns \c true if atomic reference counting is wait-free, false |
362 | otherwise. |
363 | */ |
364 | |
365 | /*! |
366 | \fn template <typename T> bool QAtomicInteger<T>::ref() |
367 | Atomically increments the value of this QAtomicInteger. Returns \c true |
368 | if the new value is non-zero, false otherwise. |
369 | |
370 | This function uses \e ordered \l {QAtomicInteger#Memory |
371 | ordering}{memory ordering} semantics, which ensures that memory |
372 | access before and after the atomic operation (in program order) |
373 | may not be re-ordered. |
374 | |
375 | \sa deref(), operator++() |
376 | */ |
377 | |
378 | /*! |
379 | \fn template <typename T> T QAtomicInteger<T>::operator++() |
380 | \since 5.3 |
381 | |
382 | Atomically pre-increments the value of this QAtomicInteger. Returns the new |
383 | value of this atomic. |
384 | |
385 | This function uses a sequentially consistent memory ordering if possible; |
386 | or "Ordered" ordering if not. |
387 | |
388 | \sa ref(), operator++(int), operator--() |
389 | */ |
390 | |
391 | /*! |
392 | \fn template <typename T> T QAtomicInteger<T>::operator++(int) |
393 | \since 5.3 |
394 | |
395 | Atomically post-increments the value of this QAtomicInteger. Returns the old |
396 | value of this atomic. |
397 | |
398 | This function uses a sequentially consistent memory ordering if possible; |
399 | or "Ordered" ordering if not. |
400 | |
401 | \sa ref(), operator++(), operator--(int) |
402 | */ |
403 | |
404 | /*! |
405 | \fn template <typename T> bool QAtomicInteger<T>::deref() |
406 | Atomically decrements the value of this QAtomicInteger. Returns \c true |
407 | if the new value is non-zero, false otherwise. |
408 | |
409 | This function uses \e ordered \l {QAtomicInteger#Memory |
410 | ordering}{memory ordering} semantics, which ensures that memory |
411 | access before and after the atomic operation (in program order) |
412 | may not be re-ordered. |
413 | |
414 | \sa ref(), operator--() |
415 | */ |
416 | |
417 | /*! |
418 | \fn template <typename T> T QAtomicInteger<T>::operator--() |
419 | \since 5.3 |
420 | |
421 | Atomically pre-decrements the value of this QAtomicInteger. Returns the new |
422 | value of this atomic. |
423 | |
424 | This function uses a sequentially consistent memory ordering if possible; |
425 | or "Ordered" ordering if not. |
426 | |
427 | \sa deref(), operator--(int), operator++() |
428 | */ |
429 | |
430 | /*! |
431 | \fn template <typename T> T QAtomicInteger<T>::operator--(int) |
432 | \since 5.3 |
433 | |
434 | Atomically post-decrements the value of this QAtomicInteger. Returns the old |
435 | value of this atomic. |
436 | |
437 | This function uses a sequentially consistent memory ordering if possible; |
438 | or "Ordered" ordering if not. |
439 | |
440 | \sa deref(), operator--(), operator++(int) |
441 | */ |
442 | |
443 | /*! |
444 | \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetNative() |
445 | |
446 | Returns \c true if test-and-set is implemented using atomic processor |
447 | instructions, false otherwise. |
448 | */ |
449 | |
450 | /*! |
451 | \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetWaitFree() |
452 | |
453 | Returns \c true if atomic test-and-set is wait-free, false otherwise. |
454 | */ |
455 | |
456 | /*! |
457 | \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelaxed(T expectedValue, T newValue) |
458 | |
459 | Atomic test-and-set. |
460 | |
461 | If the current value of this QAtomicInteger is the \a expectedValue, |
462 | the test-and-set functions assign the \a newValue to this |
463 | QAtomicInteger and return true. If the values are \e not the same, |
464 | this function does nothing and returns \c false. |
465 | |
466 | This function uses \e relaxed \l {QAtomicInteger#Memory |
467 | ordering}{memory ordering} semantics, leaving the compiler and |
468 | processor to freely reorder memory accesses. |
469 | */ |
470 | |
471 | /*! |
472 | \fn template <typename T> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue) |
473 | |
474 | Atomic test-and-set. |
475 | |
476 | If the current value of this QAtomicInteger is the \a expectedValue, |
477 | the test-and-set functions assign the \a newValue to this |
478 | QAtomicInteger and return true. If the values are \e not the same, |
479 | this function does nothing and returns \c false. |
480 | |
481 | This function uses \e acquire \l {QAtomicInteger#Memory |
482 | ordering}{memory ordering} semantics, which ensures that memory |
483 | access following the atomic operation (in program order) may not |
484 | be re-ordered before the atomic operation. |
485 | */ |
486 | |
487 | /*! |
488 | \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue) |
489 | |
490 | Atomic test-and-set. |
491 | |
492 | If the current value of this QAtomicInteger is the \a expectedValue, |
493 | the test-and-set functions assign the \a newValue to this |
494 | QAtomicInteger and return true. If the values are \e not the same, |
495 | this function does nothing and returns \c false. |
496 | |
497 | This function uses \e release \l {QAtomicInteger#Memory |
498 | ordering}{memory ordering} semantics, which ensures that memory |
499 | access before the atomic operation (in program order) may not be |
500 | re-ordered after the atomic operation. |
501 | */ |
502 | |
503 | /*! |
504 | \fn template <typename T> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue) |
505 | |
506 | Atomic test-and-set. |
507 | |
508 | If the current value of this QAtomicInteger is the \a expectedValue, |
509 | the test-and-set functions assign the \a newValue to this |
510 | QAtomicInteger and return true. If the values are \e not the same, |
511 | this function does nothing and returns \c false. |
512 | |
513 | This function uses \e ordered \l {QAtomicInteger#Memory |
514 | ordering}{memory ordering} semantics, which ensures that memory |
515 | access before and after the atomic operation (in program order) |
516 | may not be re-ordered. |
517 | */ |
518 | |
519 | /*! |
520 | \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreNative() |
521 | |
522 | Returns \c true if fetch-and-store is implemented using atomic |
523 | processor instructions, false otherwise. |
524 | */ |
525 | |
526 | /*! |
527 | \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreWaitFree() |
528 | |
529 | Returns \c true if atomic fetch-and-store is wait-free, false |
530 | otherwise. |
531 | */ |
532 | |
533 | /*! |
534 | \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelaxed(T newValue) |
535 | |
536 | Atomic fetch-and-store. |
537 | |
538 | Reads the current value of this QAtomicInteger and then assigns it the |
539 | \a newValue, returning the original value. |
540 | |
541 | This function uses \e relaxed \l {QAtomicInteger#Memory |
542 | ordering}{memory ordering} semantics, leaving the compiler and |
543 | processor to freely reorder memory accesses. |
544 | */ |
545 | |
546 | /*! |
547 | \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreAcquire(T newValue) |
548 | |
549 | Atomic fetch-and-store. |
550 | |
551 | Reads the current value of this QAtomicInteger and then assigns it the |
552 | \a newValue, returning the original value. |
553 | |
554 | This function uses \e acquire \l {QAtomicInteger#Memory |
555 | ordering}{memory ordering} semantics, which ensures that memory |
556 | access following the atomic operation (in program order) may not |
557 | be re-ordered before the atomic operation. |
558 | */ |
559 | |
560 | /*! |
561 | \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelease(T newValue) |
562 | |
563 | Atomic fetch-and-store. |
564 | |
565 | Reads the current value of this QAtomicInteger and then assigns it the |
566 | \a newValue, returning the original value. |
567 | |
568 | This function uses \e release \l {QAtomicInteger#Memory |
569 | ordering}{memory ordering} semantics, which ensures that memory |
570 | access before the atomic operation (in program order) may not be |
571 | re-ordered after the atomic operation. |
572 | */ |
573 | |
574 | /*! |
575 | \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreOrdered(T newValue) |
576 | |
577 | Atomic fetch-and-store. |
578 | |
579 | Reads the current value of this QAtomicInteger and then assigns it the |
580 | \a newValue, returning the original value. |
581 | |
582 | This function uses \e ordered \l {QAtomicInteger#Memory |
583 | ordering}{memory ordering} semantics, which ensures that memory |
584 | access before and after the atomic operation (in program order) |
585 | may not be re-ordered. |
586 | */ |
587 | |
588 | /*! |
589 | \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddNative() |
590 | |
591 | Returns \c true if fetch-and-add is implemented using atomic |
592 | processor instructions, false otherwise. |
593 | */ |
594 | |
595 | /*! |
596 | \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddWaitFree() |
597 | |
598 | Returns \c true if atomic fetch-and-add is wait-free, false |
599 | otherwise. |
600 | */ |
601 | |
602 | /*! |
603 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelaxed(T valueToAdd) |
604 | |
605 | Atomic fetch-and-add. |
606 | |
607 | Reads the current value of this QAtomicInteger and then adds |
608 | \a valueToAdd to the current value, returning the original value. |
609 | |
610 | This function uses \e relaxed \l {QAtomicInteger#Memory |
611 | ordering}{memory ordering} semantics, leaving the compiler and |
612 | processor to freely reorder memory accesses. |
613 | |
614 | \sa operator+=(), fetchAndSubRelaxed() |
615 | */ |
616 | |
617 | /*! |
618 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAddAcquire(T valueToAdd) |
619 | |
620 | Atomic fetch-and-add. |
621 | |
622 | Reads the current value of this QAtomicInteger and then adds |
623 | \a valueToAdd to the current value, returning the original value. |
624 | |
625 | This function uses \e acquire \l {QAtomicInteger#Memory |
626 | ordering}{memory ordering} semantics, which ensures that memory |
627 | access following the atomic operation (in program order) may not |
628 | be re-ordered before the atomic operation. |
629 | |
630 | \sa operator+=(), fetchAndSubAcquire() |
631 | */ |
632 | |
633 | /*! |
634 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelease(T valueToAdd) |
635 | |
636 | Atomic fetch-and-add. |
637 | |
638 | Reads the current value of this QAtomicInteger and then adds |
639 | \a valueToAdd to the current value, returning the original value. |
640 | |
641 | This function uses \e release \l {QAtomicInteger#Memory |
642 | ordering}{memory ordering} semantics, which ensures that memory |
643 | access before the atomic operation (in program order) may not be |
644 | re-ordered after the atomic operation. |
645 | |
646 | \sa operator+=(), fetchAndSubRelease() |
647 | */ |
648 | |
649 | /*! |
650 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAddOrdered(T valueToAdd) |
651 | |
652 | Atomic fetch-and-add. |
653 | |
654 | Reads the current value of this QAtomicInteger and then adds |
655 | \a valueToAdd to the current value, returning the original value. |
656 | |
657 | This function uses \e ordered \l {QAtomicInteger#Memory |
658 | ordering}{memory ordering} semantics, which ensures that memory |
659 | access before and after the atomic operation (in program order) |
660 | may not be re-ordered. |
661 | |
662 | \sa operator+=(), fetchAndSubOrdered() |
663 | */ |
664 | |
665 | /*! |
666 | \fn template <typename T> T QAtomicInteger<T>::operator+=(T value) |
667 | \since 5.3 |
668 | |
669 | Atomic add-and-fetch. |
670 | |
671 | Reads the current value of this QAtomicInteger and then adds |
672 | \a value to the current value, returning the new value. |
673 | |
674 | This function uses a sequentially consistent memory ordering if possible; |
675 | or "Ordered" ordering if not. |
676 | |
677 | \sa fetchAndAddOrdered(), operator-=() |
678 | */ |
679 | |
680 | /*! |
681 | \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelaxed(T valueToSub) |
682 | \since 5.3 |
683 | |
684 | Atomic fetch-and-sub. |
685 | |
686 | Reads the current value of this QAtomicInteger and then subtracts |
687 | \a valueToSub to the current value, returning the original value. |
688 | |
689 | This function uses \e relaxed \l {QAtomicInteger#Memory |
690 | ordering}{memory ordering} semantics, leaving the compiler and |
691 | processor to freely reorder memory accesses. |
692 | |
693 | \sa operator-=(), fetchAndAddRelaxed() |
694 | */ |
695 | |
696 | /*! |
697 | \fn template <typename T> T QAtomicInteger<T>::fetchAndSubAcquire(T valueToSub) |
698 | \since 5.3 |
699 | |
700 | Atomic fetch-and-sub. |
701 | |
702 | Reads the current value of this QAtomicInteger and then subtracts |
703 | \a valueToSub to the current value, returning the original value. |
704 | |
705 | This function uses \e acquire \l {QAtomicInteger#Memory |
706 | ordering}{memory ordering} semantics, which ensures that memory |
707 | access following the atomic operation (in program order) may not |
708 | be re-ordered before the atomic operation. |
709 | |
710 | \sa operator-=(), fetchAndAddAcquire() |
711 | */ |
712 | |
713 | /*! |
714 | \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelease(T valueToSub) |
715 | \since 5.3 |
716 | |
717 | Atomic fetch-and-sub. |
718 | |
719 | Reads the current value of this QAtomicInteger and then subtracts |
720 | \a valueToSub to the current value, returning the original value. |
721 | |
722 | This function uses \e release \l {QAtomicInteger#Memory |
723 | ordering}{memory ordering} semantics, which ensures that memory |
724 | access before the atomic operation (in program order) may not be |
725 | re-ordered after the atomic operation. |
726 | |
727 | \sa operator-=(), fetchAndAddRelease() |
728 | */ |
729 | |
730 | /*! |
731 | \fn template <typename T> T QAtomicInteger<T>::fetchAndSubOrdered(T valueToSub) |
732 | \since 5.3 |
733 | |
734 | Atomic fetch-and-sub. |
735 | |
736 | Reads the current value of this QAtomicInteger and then subtracts |
737 | \a valueToSub to the current value, returning the original value. |
738 | |
739 | This function uses \e ordered \l {QAtomicInteger#Memory |
740 | ordering}{memory ordering} semantics, which ensures that memory |
741 | access before and after the atomic operation (in program order) |
742 | may not be re-ordered. |
743 | |
744 | \sa operator-=(), fetchAndAddOrdered() |
745 | */ |
746 | |
747 | /*! |
748 | \fn template <typename T> T QAtomicInteger<T>::operator-=(T value) |
749 | \since 5.3 |
750 | |
751 | Atomic sub-and-fetch. |
752 | |
753 | Reads the current value of this QAtomicInteger and then subtracts |
754 | \a value to the current value, returning the new value. |
755 | |
756 | This function uses a sequentially consistent memory ordering if possible; |
757 | or "Ordered" ordering if not. |
758 | |
759 | \sa fetchAndSubOrdered(), operator+=() |
760 | */ |
761 | |
762 | /*! |
763 | \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelaxed(T valueToOr) |
764 | \since 5.3 |
765 | |
766 | Atomic fetch-and-or. |
767 | |
768 | Reads the current value of this QAtomicInteger and then bitwise-ORs |
769 | \a valueToOr to the current value, returning the original value. |
770 | |
771 | This function uses \e relaxed \l {QAtomicInteger#Memory |
772 | ordering}{memory ordering} semantics, leaving the compiler and |
773 | processor to freely reorder memory accesses. |
774 | |
775 | \sa operator|=() |
776 | */ |
777 | |
778 | /*! |
779 | \fn template <typename T> T QAtomicInteger<T>::fetchAndOrAcquire(T valueToOr) |
780 | \since 5.3 |
781 | |
782 | Atomic fetch-and-or. |
783 | |
784 | Reads the current value of this QAtomicInteger and then bitwise-ORs |
785 | \a valueToOr to the current value, returning the original value. |
786 | |
787 | This function uses \e acquire \l {QAtomicInteger#Memory |
788 | ordering}{memory ordering} semantics, which ensures that memory |
789 | access following the atomic operation (in program order) may not |
790 | be re-ordered before the atomic operation. |
791 | |
792 | \sa operator|=() |
793 | */ |
794 | |
795 | /*! |
796 | \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelease(T valueToOr) |
797 | \since 5.3 |
798 | |
799 | Atomic fetch-and-or. |
800 | |
801 | Reads the current value of this QAtomicInteger and then bitwise-ORs |
802 | \a valueToOr to the current value, returning the original value. |
803 | |
804 | This function uses \e release \l {QAtomicInteger#Memory |
805 | ordering}{memory ordering} semantics, which ensures that memory |
806 | access before the atomic operation (in program order) may not be |
807 | re-ordered after the atomic operation. |
808 | |
809 | \sa operator|=() |
810 | */ |
811 | |
812 | /*! |
813 | \fn template <typename T> T QAtomicInteger<T>::fetchAndOrOrdered(T valueToOr) |
814 | \since 5.3 |
815 | |
816 | Atomic fetch-and-or. |
817 | |
818 | Reads the current value of this QAtomicInteger and then bitwise-ORs |
819 | \a valueToOr to the current value, returning the original value. |
820 | |
821 | This function uses \e ordered \l {QAtomicInteger#Memory |
822 | ordering}{memory ordering} semantics, which ensures that memory |
823 | access before and after the atomic operation (in program order) |
824 | may not be re-ordered. |
825 | |
826 | \sa operator|=() |
827 | */ |
828 | |
829 | /*! |
830 | \fn template <typename T> T QAtomicInteger<T>::operator|=(T value) |
831 | \since 5.3 |
832 | |
833 | Atomic or-and-fetch. |
834 | |
835 | Reads the current value of this QAtomicInteger and then bitwise-ORs |
836 | \a value to the current value, returning the new value. |
837 | |
838 | This function uses a sequentially consistent memory ordering if possible; |
839 | or "Ordered" ordering if not. |
840 | |
841 | \sa fetchAndOrOrdered() |
842 | */ |
843 | |
844 | /*! |
845 | \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelaxed(T valueToXor) |
846 | \since 5.3 |
847 | |
848 | Atomic fetch-and-xor. |
849 | |
850 | Reads the current value of this QAtomicInteger and then bitwise-XORs |
851 | \a valueToXor to the current value, returning the original value. |
852 | |
853 | This function uses \e relaxed \l {QAtomicInteger#Memory |
854 | ordering}{memory ordering} semantics, leaving the compiler and |
855 | processor to freely reorder memory accesses. |
856 | |
857 | \sa operator^=() |
858 | */ |
859 | |
860 | /*! |
861 | \fn template <typename T> T QAtomicInteger<T>::fetchAndXorAcquire(T valueToXor) |
862 | \since 5.3 |
863 | |
864 | Atomic fetch-and-xor. |
865 | |
866 | Reads the current value of this QAtomicInteger and then bitwise-XORs |
867 | \a valueToXor to the current value, returning the original value. |
868 | |
869 | This function uses \e acquire \l {QAtomicInteger#Memory |
870 | ordering}{memory ordering} semantics, which ensures that memory |
871 | access following the atomic operation (in program order) may not |
872 | be re-ordered before the atomic operation. |
873 | |
874 | \sa operator^=() |
875 | */ |
876 | |
877 | /*! |
878 | \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelease(T valueToXor) |
879 | \since 5.3 |
880 | |
881 | Atomic fetch-and-xor. |
882 | |
883 | Reads the current value of this QAtomicInteger and then bitwise-XORs |
884 | \a valueToXor to the current value, returning the original value. |
885 | |
886 | This function uses \e release \l {QAtomicInteger#Memory |
887 | ordering}{memory ordering} semantics, which ensures that memory |
888 | access before the atomic operation (in program order) may not be |
889 | re-ordered after the atomic operation. |
890 | |
891 | \sa operator^=() |
892 | */ |
893 | |
894 | /*! |
895 | \fn template <typename T> T QAtomicInteger<T>::fetchAndXorOrdered(T valueToXor) |
896 | \since 5.3 |
897 | |
898 | Atomic fetch-and-xor. |
899 | |
900 | Reads the current value of this QAtomicInteger and then bitwise-XORs |
901 | \a valueToXor to the current value, returning the original value. |
902 | |
903 | This function uses \e ordered \l {QAtomicInteger#Memory |
904 | ordering}{memory ordering} semantics, which ensures that memory |
905 | access before and after the atomic operation (in program order) |
906 | may not be re-ordered. |
907 | |
908 | \sa operator^=() |
909 | */ |
910 | |
911 | /*! |
912 | \fn template <typename T> T QAtomicInteger<T>::operator^=(T value) |
913 | \since 5.3 |
914 | |
915 | Atomic xor-and-fetch. |
916 | |
917 | Reads the current value of this QAtomicInteger and then bitwise-XORs |
918 | \a value to the current value, returning the new value. |
919 | |
920 | This function uses a sequentially consistent memory ordering if possible; |
921 | or "Ordered" ordering if not. |
922 | |
923 | \sa fetchAndXorOrdered() |
924 | */ |
925 | |
926 | /*! |
927 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelaxed(T valueToAnd) |
928 | \since 5.3 |
929 | |
930 | Atomic fetch-and-and. |
931 | |
932 | Reads the current value of this QAtomicInteger and then bitwise-ANDs |
933 | \a valueToAnd to the current value, returning the original value. |
934 | |
935 | This function uses \e relaxed \l {QAtomicInteger#Memory |
936 | ordering}{memory ordering} semantics, leaving the compiler and |
937 | processor to freely reorder memory accesses. |
938 | |
939 | \sa operator&=() |
940 | */ |
941 | |
942 | /*! |
943 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAndAcquire(T valueToAnd) |
944 | \since 5.3 |
945 | |
946 | Atomic fetch-and-and. |
947 | |
948 | Reads the current value of this QAtomicInteger and then bitwise-ANDs |
949 | \a valueToAnd to the current value, returning the original value. |
950 | |
951 | This function uses \e acquire \l {QAtomicInteger#Memory |
952 | ordering}{memory ordering} semantics, which ensures that memory |
953 | access following the atomic operation (in program order) may not |
954 | be re-ordered before the atomic operation. |
955 | |
956 | \sa operator&=() |
957 | */ |
958 | |
959 | /*! |
960 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelease(T valueToAnd) |
961 | \since 5.3 |
962 | |
963 | Atomic fetch-and-and. |
964 | |
965 | Reads the current value of this QAtomicInteger and then bitwise-ANDs |
966 | \a valueToAnd to the current value, returning the original value. |
967 | |
968 | This function uses \e release \l {QAtomicInteger#Memory |
969 | ordering}{memory ordering} semantics, which ensures that memory |
970 | access before the atomic operation (in program order) may not be |
971 | re-ordered after the atomic operation. |
972 | |
973 | \sa operator&=() |
974 | */ |
975 | |
976 | /*! |
977 | \fn template <typename T> T QAtomicInteger<T>::fetchAndAndOrdered(T valueToAnd) |
978 | \since 5.3 |
979 | |
980 | Atomic fetch-and-and. |
981 | |
982 | Reads the current value of this QAtomicInteger and then bitwise-ANDs |
983 | \a valueToAnd to the current value, returning the original value. |
984 | |
985 | This function uses \e ordered \l {QAtomicInteger#Memory |
986 | ordering}{memory ordering} semantics, which ensures that memory |
987 | access before and after the atomic operation (in program order) |
988 | may not be re-ordered. |
989 | |
990 | \sa operator&=() |
991 | */ |
992 | |
993 | /*! |
994 | \fn template <typename T> T QAtomicInteger<T>::operator&=(T value) |
995 | \since 5.3 |
996 | |
997 | Atomic add-and-fetch. |
998 | |
999 | Reads the current value of this QAtomicInteger and then bitwise-ANDs |
1000 | \a value to the current value, returning the new value. |
1001 | |
1002 | This function uses a sequentially consistent memory ordering if possible; |
1003 | or "Ordered" ordering if not. |
1004 | |
1005 | \sa fetchAndAndOrdered() |
1006 | */ |
1007 | |
1008 | /*! |
1009 | \macro Q_ATOMIC_INTnn_IS_SUPPORTED |
1010 | \relates QAtomicInteger |
1011 | |
1012 | This macro is defined if atomic integers of size \e{nn} (in bits) are |
1013 | supported in this compiler / architecture combination. |
1014 | Q_ATOMIC_INT32_IS_SUPPORTED is always defined. |
1015 | |
1016 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1017 | */ |
1018 | |
1019 | /*! |
1020 | \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE |
1021 | \relates QAtomicInteger |
1022 | |
1023 | This macro is defined if and only if all generations of your |
1024 | processor support atomic reference counting. |
1025 | |
1026 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1027 | */ |
1028 | |
1029 | /*! |
1030 | \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE |
1031 | \relates QAtomicInteger |
1032 | |
1033 | This macro is defined when only certain generations of the |
1034 | processor support atomic reference counting. Use the |
1035 | QAtomicInteger<T>::isReferenceCountingNative() function to check what |
1036 | your processor supports. |
1037 | |
1038 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1039 | */ |
1040 | |
1041 | /*! |
1042 | \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_NOT_NATIVE |
1043 | \relates QAtomicInteger |
1044 | |
1045 | This macro is defined when the hardware does not support atomic |
1046 | reference counting. |
1047 | |
1048 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1049 | */ |
1050 | |
1051 | /*! |
1052 | \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_WAIT_FREE |
1053 | \relates QAtomicInteger |
1054 | |
1055 | This macro is defined together with |
1056 | Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE to indicate that |
1057 | the reference counting is wait-free. |
1058 | |
1059 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1060 | */ |
1061 | |
1062 | /*! |
1063 | \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE |
1064 | \relates QAtomicInteger |
1065 | |
1066 | This macro is defined if and only if your processor supports |
1067 | atomic test-and-set on integers. |
1068 | |
1069 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1070 | */ |
1071 | |
1072 | /*! |
1073 | \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_SOMETIMES_NATIVE |
1074 | \relates QAtomicInteger |
1075 | |
1076 | This macro is defined when only certain generations of the |
1077 | processor support atomic test-and-set on integers. Use the |
1078 | QAtomicInteger<T>::isTestAndSetNative() function to check what your |
1079 | processor supports. |
1080 | |
1081 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1082 | */ |
1083 | |
1084 | /*! |
1085 | \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_NOT_NATIVE |
1086 | \relates QAtomicInteger |
1087 | |
1088 | This macro is defined when the hardware does not support atomic |
1089 | test-and-set on integers. |
1090 | |
1091 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1092 | */ |
1093 | |
1094 | /*! |
1095 | \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_WAIT_FREE |
1096 | \relates QAtomicInteger |
1097 | |
1098 | This macro is defined together with |
1099 | Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that the |
1100 | atomic test-and-set on integers is wait-free. |
1101 | |
1102 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1103 | */ |
1104 | |
1105 | /*! |
1106 | \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE |
1107 | \relates QAtomicInteger |
1108 | |
1109 | This macro is defined if and only if your processor supports |
1110 | atomic fetch-and-store on integers. |
1111 | |
1112 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1113 | */ |
1114 | |
1115 | /*! |
1116 | \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_SOMETIMES_NATIVE |
1117 | \relates QAtomicInteger |
1118 | |
1119 | This macro is defined when only certain generations of the |
1120 | processor support atomic fetch-and-store on integers. Use the |
1121 | QAtomicInteger<T>::isFetchAndStoreNative() function to check what your |
1122 | processor supports. |
1123 | |
1124 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1125 | */ |
1126 | |
1127 | /*! |
1128 | \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_NOT_NATIVE |
1129 | \relates QAtomicInteger |
1130 | |
1131 | This macro is defined when the hardware does not support atomic |
1132 | fetch-and-store on integers. |
1133 | |
1134 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1135 | */ |
1136 | |
1137 | /*! |
1138 | \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_WAIT_FREE |
1139 | \relates QAtomicInteger |
1140 | |
1141 | This macro is defined together with |
1142 | Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that the |
1143 | atomic fetch-and-store on integers is wait-free. |
1144 | |
1145 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1146 | */ |
1147 | |
1148 | /*! |
1149 | \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE |
1150 | \relates QAtomicInteger |
1151 | |
1152 | This macro is defined if and only if your processor supports |
1153 | atomic fetch-and-add on integers. |
1154 | |
1155 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1156 | */ |
1157 | |
1158 | /*! |
1159 | \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_SOMETIMES_NATIVE |
1160 | \relates QAtomicInteger |
1161 | |
1162 | This macro is defined when only certain generations of the |
1163 | processor support atomic fetch-and-add on integers. Use the |
1164 | QAtomicInteger<T>::isFetchAndAddNative() function to check what your |
1165 | processor supports. |
1166 | |
1167 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1168 | */ |
1169 | |
1170 | /*! |
1171 | \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_NOT_NATIVE |
1172 | \relates QAtomicInteger |
1173 | |
1174 | This macro is defined when the hardware does not support atomic |
1175 | fetch-and-add on integers. |
1176 | |
1177 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1178 | */ |
1179 | |
1180 | /*! |
1181 | \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_WAIT_FREE |
1182 | \relates QAtomicInteger |
1183 | |
1184 | This macro is defined together with |
1185 | Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that the |
1186 | atomic fetch-and-add on integers is wait-free. |
1187 | |
1188 | \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
1189 | */ |
1190 | |
1191 | |
1192 | |
1193 | |
1194 | /*! |
1195 | \class QAtomicPointer |
1196 | \inmodule QtCore |
1197 | \brief The QAtomicPointer class is a template class that provides platform-independent atomic operations on pointers. |
1198 | \since 4.4 |
1199 | |
1200 | \ingroup thread |
1201 | |
1202 | For atomic operations on integers, see the QAtomicInteger class. |
1203 | |
1204 | An \e atomic operation is a complex operation that completes without interruption. |
1205 | The QAtomicPointer class provides atomic test-and-set, fetch-and-store, and fetch-and-add for pointers. |
1206 | |
1207 | \section1 The Atomic API |
1208 | |
1209 | \section2 Memory ordering |
1210 | |
1211 | QAtomicPointer provides several implementations of the atomic |
1212 | test-and-set, fetch-and-store, and fetch-and-add functions. Each |
1213 | implementation defines a memory ordering semantic that describes |
1214 | how memory accesses surrounding the atomic instruction are |
1215 | executed by the processor. Since many modern architectures allow |
1216 | out-of-order execution and memory ordering, using the correct |
1217 | semantic is necessary to ensure that your application functions |
1218 | properly on all processors. |
1219 | |
1220 | \list |
1221 | |
1222 | \li Relaxed - memory ordering is unspecified, leaving the compiler |
1223 | and processor to freely reorder memory accesses. |
1224 | |
1225 | \li Acquire - memory access following the atomic operation (in |
1226 | program order) may not be re-ordered before the atomic operation. |
1227 | |
1228 | \li Release - memory access before the atomic operation (in program |
1229 | order) may not be re-ordered after the atomic operation. |
1230 | |
1231 | \li Ordered - the same Acquire and Release semantics combined. |
1232 | |
1233 | \endlist |
1234 | |
1235 | \section2 Test-and-set |
1236 | |
1237 | If the current value of the QAtomicPointer is an expected value, |
1238 | the test-and-set functions assign a new value to the |
1239 | QAtomicPointer and return true. If values are \a not the same, |
1240 | these functions do nothing and return false. This operation |
1241 | equates to the following code: |
1242 | |
1243 | \snippet code/src_corelib_thread_qatomic.cpp 4 |
1244 | |
1245 | There are 4 test-and-set functions: testAndSetRelaxed(), |
1246 | testAndSetAcquire(), testAndSetRelease(), and |
1247 | testAndSetOrdered(). See above for an explanation of the different |
1248 | memory ordering semantics. |
1249 | |
1250 | \section2 Fetch-and-store |
1251 | |
1252 | The atomic fetch-and-store functions read the current value of the |
1253 | QAtomicPointer and then assign a new value, returning the original |
1254 | value. This operation equates to the following code: |
1255 | |
1256 | \snippet code/src_corelib_thread_qatomic.cpp 5 |
1257 | |
1258 | There are 4 fetch-and-store functions: fetchAndStoreRelaxed(), |
1259 | fetchAndStoreAcquire(), fetchAndStoreRelease(), and |
1260 | fetchAndStoreOrdered(). See above for an explanation of the |
1261 | different memory ordering semantics. |
1262 | |
1263 | \section2 Fetch-and-add |
1264 | |
1265 | The atomic fetch-and-add functions read the current value of the |
1266 | QAtomicPointer and then add the given value to the current value, |
1267 | returning the original value. This operation equates to the |
1268 | following code: |
1269 | |
1270 | \snippet code/src_corelib_thread_qatomic.cpp 6 |
1271 | |
1272 | There are 4 fetch-and-add functions: fetchAndAddRelaxed(), |
1273 | fetchAndAddAcquire(), fetchAndAddRelease(), and |
1274 | fetchAndAddOrdered(). See above for an explanation of the |
1275 | different memory ordering semantics. |
1276 | |
1277 | \section1 Feature Tests for the Atomic API |
1278 | |
1279 | Providing a platform-independent atomic API that works on all |
1280 | processors is challenging. The API provided by QAtomicPointer is |
1281 | guaranteed to work atomically on all processors. However, since |
1282 | not all processors implement support for every operation provided |
1283 | by QAtomicPointer, it is necessary to expose information about the |
1284 | processor. |
1285 | |
1286 | You can check at compile time which features are supported on your |
1287 | hardware using various macros. These will tell you if your |
1288 | hardware always, sometimes, or does not support a particular |
1289 | operation. The macros have the form |
1290 | Q_ATOMIC_POINTER_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{OPERATION} is |
1291 | one of TEST_AND_SET, FETCH_AND_STORE, or FETCH_AND_ADD, and |
1292 | \e{HOW} is one of ALWAYS, SOMETIMES, or NOT. There will always be |
1293 | exactly one defined macro per operation. For example, if |
1294 | Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE is defined, neither |
1295 | Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE nor |
1296 | Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE will be defined. |
1297 | |
1298 | An operation that completes in constant time is said to be |
1299 | wait-free. Such operations are not implemented using locks or |
1300 | loops of any kind. For atomic operations that are always |
1301 | supported, and that are wait-free, Qt defines the |
1302 | Q_ATOMIC_POINTER_\e{OPERATION}_IS_WAIT_FREE in addition to the |
1303 | Q_ATOMIC_POINTER_\e{OPERATION}_IS_ALWAYS_NATIVE. |
1304 | |
1305 | In cases where an atomic operation is only supported in newer |
1306 | generations of the processor, QAtomicPointer also provides a way |
1307 | to check at runtime what your hardware supports with the |
1308 | isTestAndSetNative(), isFetchAndStoreNative(), and |
1309 | isFetchAndAddNative() functions. Wait-free implementations can be |
1310 | detected using the isTestAndSetWaitFree(), |
1311 | isFetchAndStoreWaitFree(), and isFetchAndAddWaitFree() functions. |
1312 | |
1313 | Below is a complete list of all feature macros for QAtomicPointer: |
1314 | |
1315 | \list |
1316 | |
1317 | \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE |
1318 | \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE |
1319 | \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE |
1320 | \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE |
1321 | |
1322 | \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE |
1323 | \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE |
1324 | \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE |
1325 | \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE |
1326 | |
1327 | \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE |
1328 | \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE |
1329 | \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE |
1330 | \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE |
1331 | |
1332 | \endlist |
1333 | |
1334 | \sa QAtomicInteger |
1335 | */ |
1336 | |
1337 | /*! |
1338 | \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(T *value) |
1339 | |
1340 | Constructs a QAtomicPointer with the given \a value. |
1341 | */ |
1342 | |
1343 | /*! |
1344 | \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(const QAtomicPointer<T> &other) |
1345 | |
1346 | Constructs a copy of \a other. |
1347 | */ |
1348 | |
1349 | /*! |
1350 | \fn template <typename T> QAtomicPointer &QAtomicPointer<T>::operator=(const QAtomicPointer &other) |
1351 | |
1352 | Assigns \a other to this QAtomicPointer and returns a reference to |
1353 | this QAtomicPointer. |
1354 | */ |
1355 | |
1356 | /*! |
1357 | \fn template <typename T> T *QAtomicPointer<T>::load() const |
1358 | \obsolete |
1359 | |
1360 | Use loadRelaxed() instead. |
1361 | |
1362 | Atomically loads the value of this QAtomicPointer using relaxed memory |
1363 | ordering. The value is not modified in any way, but note that there's no |
1364 | guarantee that it remains so. |
1365 | |
1366 | \sa storeRelaxed(), loadAcquire() |
1367 | */ |
1368 | |
1369 | /*! |
1370 | \fn template <typename T> T *QAtomicPointer<T>::loadRelaxed() const |
1371 | \since 5.14 |
1372 | |
1373 | Atomically loads the value of this QAtomicPointer using relaxed memory |
1374 | ordering. The value is not modified in any way, but note that there's no |
1375 | guarantee that it remains so. |
1376 | |
1377 | \sa storeRelaxed(), loadAcquire() |
1378 | */ |
1379 | |
1380 | |
1381 | /*! |
1382 | \fn template <typename T> T *QAtomicPointer<T>::loadAcquire() const |
1383 | |
1384 | Atomically loads the value of this QAtomicPointer using the "Acquire" memory |
1385 | ordering. The value is not modified in any way, but note that there's no |
1386 | guarantee that it remains so. |
1387 | |
1388 | \sa storeRelease(), loadRelaxed() |
1389 | */ |
1390 | |
1391 | /*! |
1392 | \fn template <typename T> void QAtomicPointer<T>::store(T *newValue) |
1393 | \obsolete |
1394 | |
1395 | Use storeRelaxed() instead. |
1396 | |
1397 | Atomically stores the \a newValue value into this atomic type, using |
1398 | relaxed memory ordering. |
1399 | |
1400 | \sa storeRelease(), loadRelaxed() |
1401 | */ |
1402 | |
1403 | /*! |
1404 | \fn template <typename T> void QAtomicPointer<T>::storeRelaxed(T *newValue) |
1405 | \since 5.14 |
1406 | |
1407 | Atomically stores the \a newValue value into this atomic type, using |
1408 | relaxed memory ordering. |
1409 | |
1410 | \sa storeRelease(), loadRelaxed() |
1411 | */ |
1412 | |
1413 | /*! |
1414 | \fn template <typename T> void QAtomicPointer<T>::storeRelease(T *newValue) |
1415 | |
1416 | Atomically stores the \a newValue value into this atomic type, using |
1417 | the "Release" memory ordering. |
1418 | |
1419 | \sa storeRelaxed(), loadRelaxed() |
1420 | */ |
1421 | |
1422 | /*! |
1423 | \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative() |
1424 | |
1425 | Returns \c true if test-and-set is implemented using atomic processor |
1426 | instructions, false otherwise. |
1427 | */ |
1428 | |
1429 | /*! |
1430 | \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetWaitFree() |
1431 | |
1432 | Returns \c true if atomic test-and-set is wait-free, false otherwise. |
1433 | */ |
1434 | |
1435 | /*! |
1436 | \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) |
1437 | |
1438 | Atomic test-and-set. |
1439 | |
1440 | If the current value of this QAtomicPointer is the \a expectedValue, |
1441 | the test-and-set functions assign the \a newValue to this |
1442 | QAtomicPointer and return true. If the values are \e not the same, |
1443 | this function does nothing and returns \c false. |
1444 | |
1445 | This function uses \e relaxed \l {QAtomicPointer#Memory |
1446 | ordering}{memory ordering} semantics, leaving the compiler and |
1447 | processor to freely reorder memory accesses. |
1448 | */ |
1449 | |
1450 | /*! |
1451 | \fn template <typename T> bool QAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) |
1452 | |
1453 | Atomic test-and-set. |
1454 | |
1455 | If the current value of this QAtomicPointer is the \a expectedValue, |
1456 | the test-and-set functions assign the \a newValue to this |
1457 | QAtomicPointer and return true. If the values are \e not the same, |
1458 | this function does nothing and returns \c false. |
1459 | |
1460 | This function uses \e acquire \l {QAtomicPointer#Memory |
1461 | ordering}{memory ordering} semantics, which ensures that memory |
1462 | access following the atomic operation (in program order) may not |
1463 | be re-ordered before the atomic operation. |
1464 | */ |
1465 | |
1466 | /*! |
1467 | \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) |
1468 | |
1469 | Atomic test-and-set. |
1470 | |
1471 | If the current value of this QAtomicPointer is the \a expectedValue, |
1472 | the test-and-set functions assign the \a newValue to this |
1473 | QAtomicPointer and return true. If the values are \e not the same, |
1474 | this function does nothing and returns \c false. |
1475 | |
1476 | This function uses \e release \l {QAtomicPointer#Memory |
1477 | ordering}{memory ordering} semantics, which ensures that memory |
1478 | access before the atomic operation (in program order) may not be |
1479 | re-ordered after the atomic operation. |
1480 | */ |
1481 | |
1482 | /*! |
1483 | \fn template <typename T> bool QAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) |
1484 | |
1485 | Atomic test-and-set. |
1486 | |
1487 | If the current value of this QAtomicPointer is the \a expectedValue, |
1488 | the test-and-set functions assign the \a newValue to this |
1489 | QAtomicPointer and return true. If the values are \e not the same, |
1490 | this function does nothing and returns \c false. |
1491 | |
1492 | This function uses \e ordered \l {QAtomicPointer#Memory |
1493 | ordering}{memory ordering} semantics, which ensures that memory |
1494 | access before and after the atomic operation (in program order) |
1495 | may not be re-ordered. |
1496 | */ |
1497 | |
1498 | /*! |
1499 | \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreNative() |
1500 | |
1501 | Returns \c true if fetch-and-store is implemented using atomic |
1502 | processor instructions, false otherwise. |
1503 | */ |
1504 | |
1505 | /*! |
1506 | \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreWaitFree() |
1507 | |
1508 | Returns \c true if atomic fetch-and-store is wait-free, false |
1509 | otherwise. |
1510 | */ |
1511 | |
1512 | /*! |
1513 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) |
1514 | |
1515 | Atomic fetch-and-store. |
1516 | |
1517 | Reads the current value of this QAtomicPointer and then assigns it the |
1518 | \a newValue, returning the original value. |
1519 | |
1520 | This function uses \e relaxed \l {QAtomicPointer#Memory |
1521 | ordering}{memory ordering} semantics, leaving the compiler and |
1522 | processor to freely reorder memory accesses. |
1523 | */ |
1524 | |
1525 | /*! |
1526 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) |
1527 | |
1528 | Atomic fetch-and-store. |
1529 | |
1530 | Reads the current value of this QAtomicPointer and then assigns it the |
1531 | \a newValue, returning the original value. |
1532 | |
1533 | This function uses \e acquire \l {QAtomicPointer#Memory |
1534 | ordering}{memory ordering} semantics, which ensures that memory |
1535 | access following the atomic operation (in program order) may not |
1536 | be re-ordered before the atomic operation. |
1537 | */ |
1538 | |
1539 | /*! |
1540 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelease(T *newValue) |
1541 | |
1542 | Atomic fetch-and-store. |
1543 | |
1544 | Reads the current value of this QAtomicPointer and then assigns it the |
1545 | \a newValue, returning the original value. |
1546 | |
1547 | This function uses \e release \l {QAtomicPointer#Memory |
1548 | ordering}{memory ordering} semantics, which ensures that memory |
1549 | access before the atomic operation (in program order) may not be |
1550 | re-ordered after the atomic operation. |
1551 | */ |
1552 | |
1553 | /*! |
1554 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) |
1555 | |
1556 | Atomic fetch-and-store. |
1557 | |
1558 | Reads the current value of this QAtomicPointer and then assigns it the |
1559 | \a newValue, returning the original value. |
1560 | |
1561 | This function uses \e ordered \l {QAtomicPointer#Memory |
1562 | ordering}{memory ordering} semantics, which ensures that memory |
1563 | access before and after the atomic operation (in program order) |
1564 | may not be re-ordered. |
1565 | */ |
1566 | |
1567 | /*! |
1568 | \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddNative() |
1569 | |
1570 | Returns \c true if fetch-and-add is implemented using atomic |
1571 | processor instructions, false otherwise. |
1572 | */ |
1573 | |
1574 | /*! |
1575 | \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddWaitFree() |
1576 | |
1577 | Returns \c true if atomic fetch-and-add is wait-free, false |
1578 | otherwise. |
1579 | */ |
1580 | |
1581 | /*! |
1582 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) |
1583 | |
1584 | Atomic fetch-and-add. |
1585 | |
1586 | Reads the current value of this QAtomicPointer and then adds |
1587 | \a valueToAdd to the current value, returning the original value. |
1588 | |
1589 | This function uses \e relaxed \l {QAtomicPointer#Memory |
1590 | ordering}{memory ordering} semantics, leaving the compiler and |
1591 | processor to freely reorder memory accesses. |
1592 | */ |
1593 | |
1594 | /*! |
1595 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) |
1596 | |
1597 | Atomic fetch-and-add. |
1598 | |
1599 | Reads the current value of this QAtomicPointer and then adds |
1600 | \a valueToAdd to the current value, returning the original value. |
1601 | |
1602 | This function uses \e acquire \l {QAtomicPointer#Memory |
1603 | ordering}{memory ordering} semantics, which ensures that memory |
1604 | access following the atomic operation (in program order) may not |
1605 | be re-ordered before the atomic operation. |
1606 | */ |
1607 | |
1608 | /*! |
1609 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) |
1610 | |
1611 | Atomic fetch-and-add. |
1612 | |
1613 | Reads the current value of this QAtomicPointer and then adds |
1614 | \a valueToAdd to the current value, returning the original value. |
1615 | |
1616 | This function uses \e release \l {QAtomicPointer#Memory |
1617 | ordering}{memory ordering} semantics, which ensures that memory |
1618 | access before the atomic operation (in program order) may not be |
1619 | re-ordered after the atomic operation. |
1620 | */ |
1621 | |
1622 | /*! |
1623 | \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) |
1624 | |
1625 | Atomic fetch-and-add. |
1626 | |
1627 | Reads the current value of this QAtomicPointer and then adds |
1628 | \a valueToAdd to the current value, returning the original value. |
1629 | |
1630 | This function uses \e ordered \l {QAtomicPointer#Memory |
1631 | ordering}{memory ordering} semantics, which ensures that memory |
1632 | access before and after the atomic operation (in program order) |
1633 | may not be re-ordered. |
1634 | */ |
1635 | |
1636 | /*! |
1637 | \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE |
1638 | \relates QAtomicPointer |
1639 | |
1640 | This macro is defined if and only if your processor supports |
1641 | atomic test-and-set on pointers. |
1642 | */ |
1643 | |
1644 | /*! |
1645 | \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE |
1646 | \relates QAtomicPointer |
1647 | |
1648 | This macro is defined when only certain generations of the |
1649 | processor support atomic test-and-set on pointers. Use the |
1650 | QAtomicPointer::isTestAndSetNative() function to check what your |
1651 | processor supports. |
1652 | */ |
1653 | |
1654 | /*! |
1655 | \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE |
1656 | \relates QAtomicPointer |
1657 | |
1658 | This macro is defined when the hardware does not support atomic |
1659 | test-and-set on pointers. |
1660 | */ |
1661 | |
1662 | /*! |
1663 | \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE |
1664 | \relates QAtomicPointer |
1665 | |
1666 | This macro is defined together with |
1667 | Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that |
1668 | the atomic test-and-set on pointers is wait-free. |
1669 | */ |
1670 | |
1671 | /*! |
1672 | \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE |
1673 | \relates QAtomicPointer |
1674 | |
1675 | This macro is defined if and only if your processor supports |
1676 | atomic fetch-and-store on pointers. |
1677 | */ |
1678 | |
1679 | /*! |
1680 | \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE |
1681 | \relates QAtomicPointer |
1682 | |
1683 | This macro is defined when only certain generations of the |
1684 | processor support atomic fetch-and-store on pointers. Use the |
1685 | QAtomicPointer::isFetchAndStoreNative() function to check what |
1686 | your processor supports. |
1687 | */ |
1688 | |
1689 | /*! |
1690 | \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE |
1691 | \relates QAtomicPointer |
1692 | |
1693 | This macro is defined when the hardware does not support atomic |
1694 | fetch-and-store on pointers. |
1695 | */ |
1696 | |
1697 | /*! |
1698 | \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE |
1699 | \relates QAtomicPointer |
1700 | |
1701 | This macro is defined together with |
1702 | Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that |
1703 | the atomic fetch-and-store on pointers is wait-free. |
1704 | */ |
1705 | |
1706 | /*! |
1707 | \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE |
1708 | \relates QAtomicPointer |
1709 | |
1710 | This macro is defined if and only if your processor supports |
1711 | atomic fetch-and-add on pointers. |
1712 | */ |
1713 | |
1714 | /*! |
1715 | \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE |
1716 | \relates QAtomicPointer |
1717 | |
1718 | This macro is defined when only certain generations of the |
1719 | processor support atomic fetch-and-add on pointers. Use the |
1720 | QAtomicPointer::isFetchAndAddNative() function to check what your |
1721 | processor supports. |
1722 | */ |
1723 | |
1724 | /*! |
1725 | \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE |
1726 | \relates QAtomicPointer |
1727 | |
1728 | This macro is defined when the hardware does not support atomic |
1729 | fetch-and-add on pointers. |
1730 | */ |
1731 | |
1732 | /*! |
1733 | \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE |
1734 | \relates QAtomicPointer |
1735 | |
1736 | This macro is defined together with |
1737 | Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that |
1738 | the atomic fetch-and-add on pointers is wait-free. |
1739 | */ |
1740 | |
1741 | // static checks |
1742 | #ifndef Q_ATOMIC_INT32_IS_SUPPORTED |
1743 | # error "Q_ATOMIC_INT32_IS_SUPPORTED must be defined" |
1744 | #endif |
1745 | #if !defined(Q_ATOMIC_INT64_IS_SUPPORTED) && QT_POINTER_SIZE == 8 |
1746 | // 64-bit platform |
1747 | # error "Q_ATOMIC_INT64_IS_SUPPORTED must be defined on a 64-bit platform" |
1748 | #endif |
1749 | |
1750 | QT_BEGIN_NAMESPACE |
1751 | |
1752 | // The following specializations must always be defined |
1753 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned>)); |
1754 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<long>)); |
1755 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned long>)); |
1756 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<quintptr>)); |
1757 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<qptrdiff>)); |
1758 | #ifdef Q_COMPILER_UNICODE_STRINGS |
1759 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<char32_t>)); |
1760 | #endif |
1761 | |
1762 | #ifdef Q_ATOMIC_INT16_IS_SUPPORTED |
1763 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<short>)); |
1764 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned short>)); |
1765 | # if WCHAR_MAX < 0x10000 |
1766 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>)); |
1767 | # endif |
1768 | # ifdef Q_COMPILER_UNICODE_STRINGS |
1769 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<char16_t>)); |
1770 | # endif |
1771 | #endif |
1772 | |
1773 | #ifdef Q_ATOMIC_INT64_IS_SUPPORTED |
1774 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<qint64>)); |
1775 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<quint64>)); |
1776 | #endif |
1777 | |
1778 | #if WCHAR_MAX == INT_MAX |
1779 | Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>)); |
1780 | #endif |
1781 | |
1782 | QT_END_NAMESPACE |
1783 | |