Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:27:57

0001 // Copyright (C) 2017 The Qt Company Ltd.
0002 // Copyright (C) 2016 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 // Qt-Security score:significant reason:default
0005 
0006 #ifndef QATOMIC_H
0007 #define QATOMIC_H
0008 
0009 #include <QtCore/qbasicatomic.h>
0010 
0011 QT_BEGIN_NAMESPACE
0012 
0013 QT_WARNING_PUSH
0014 QT_WARNING_DISABLE_GCC("-Wextra")
0015 
0016 // High-level atomic integer operations
0017 template <typename T>
0018 class QAtomicInteger : public QBasicAtomicInteger<T>
0019 {
0020 public:
0021     // Non-atomic API
0022     constexpr QAtomicInteger(T value = 0) noexcept : QBasicAtomicInteger<T>(value) {}
0023 
0024     inline QAtomicInteger(const QAtomicInteger &other) noexcept
0025         : QBasicAtomicInteger<T>()
0026     {
0027         this->storeRelease(other.loadAcquire());
0028     }
0029 
0030     inline QAtomicInteger &operator=(const QAtomicInteger &other) noexcept
0031     {
0032         this->storeRelease(other.loadAcquire());
0033         return *this;
0034     }
0035 
0036 #ifdef Q_QDOC
0037     T loadRelaxed() const;
0038     T loadAcquire() const;
0039     void storeRelaxed(T newValue);
0040     void storeRelease(T newValue);
0041 
0042     operator T() const;
0043     QAtomicInteger &operator=(T);
0044 
0045     static constexpr bool isReferenceCountingNative();
0046     static constexpr bool isReferenceCountingWaitFree();
0047 
0048     bool ref();
0049     bool deref();
0050 
0051     static constexpr bool isTestAndSetNative();
0052     static constexpr bool isTestAndSetWaitFree();
0053 
0054     bool testAndSetRelaxed(T expectedValue, T newValue);
0055     bool testAndSetAcquire(T expectedValue, T newValue);
0056     bool testAndSetRelease(T expectedValue, T newValue);
0057     bool testAndSetOrdered(T expectedValue, T newValue);
0058 
0059     bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue);
0060     bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue);
0061     bool testAndSetRelease(T expectedValue, T newValue, T &currentValue);
0062     bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue);
0063 
0064     static constexpr bool isFetchAndStoreNative();
0065     static constexpr bool isFetchAndStoreWaitFree();
0066 
0067     T fetchAndStoreRelaxed(T newValue);
0068     T fetchAndStoreAcquire(T newValue);
0069     T fetchAndStoreRelease(T newValue);
0070     T fetchAndStoreOrdered(T newValue);
0071 
0072     static constexpr bool isFetchAndAddNative();
0073     static constexpr bool isFetchAndAddWaitFree();
0074 
0075     T fetchAndAddRelaxed(T valueToAdd);
0076     T fetchAndAddAcquire(T valueToAdd);
0077     T fetchAndAddRelease(T valueToAdd);
0078     T fetchAndAddOrdered(T valueToAdd);
0079 
0080     T fetchAndSubRelaxed(T valueToSub);
0081     T fetchAndSubAcquire(T valueToSub);
0082     T fetchAndSubRelease(T valueToSub);
0083     T fetchAndSubOrdered(T valueToSub);
0084 
0085     T fetchAndOrRelaxed(T valueToOr);
0086     T fetchAndOrAcquire(T valueToOr);
0087     T fetchAndOrRelease(T valueToOr);
0088     T fetchAndOrOrdered(T valueToOr);
0089 
0090     T fetchAndAndRelaxed(T valueToAnd);
0091     T fetchAndAndAcquire(T valueToAnd);
0092     T fetchAndAndRelease(T valueToAnd);
0093     T fetchAndAndOrdered(T valueToAnd);
0094 
0095     T fetchAndXorRelaxed(T valueToXor);
0096     T fetchAndXorAcquire(T valueToXor);
0097     T fetchAndXorRelease(T valueToXor);
0098     T fetchAndXorOrdered(T valueToXor);
0099 
0100     T operator++();
0101     T operator++(int);
0102     T operator--();
0103     T operator--(int);
0104     T operator+=(T value);
0105     T operator-=(T value);
0106     T operator|=(T value);
0107     T operator&=(T value);
0108     T operator^=(T value);
0109 #endif
0110 };
0111 
0112 class QAtomicInt : public QAtomicInteger<int>
0113 {
0114 public:
0115     // Non-atomic API
0116     // We could use QT_COMPILER_INHERITING_CONSTRUCTORS, but we need only one;
0117     // the implicit definition for all the others is fine.
0118     constexpr QAtomicInt(int value = 0) noexcept : QAtomicInteger<int>(value) {}
0119 };
0120 
0121 // High-level atomic pointer operations
0122 template <typename T>
0123 class QAtomicPointer : public QBasicAtomicPointer<T>
0124 {
0125 public:
0126     constexpr QAtomicPointer(T *value = nullptr) noexcept : QBasicAtomicPointer<T>(value) {}
0127 
0128     inline QAtomicPointer(const QAtomicPointer<T> &other) noexcept
0129         : QBasicAtomicPointer<T>()
0130     {
0131         this->storeRelease(other.loadAcquire());
0132     }
0133 
0134     inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) noexcept
0135     {
0136         this->storeRelease(other.loadAcquire());
0137         return *this;
0138     }
0139 
0140 #ifdef Q_QDOC
0141     T *loadAcquire() const;
0142     T *loadRelaxed() const;
0143     void storeRelaxed(T *newValue);
0144     void storeRelease(T *newValue);
0145 
0146     static constexpr bool isTestAndSetNative();
0147     static constexpr bool isTestAndSetWaitFree();
0148 
0149     bool testAndSetRelaxed(T *expectedValue, T *newValue);
0150     bool testAndSetAcquire(T *expectedValue, T *newValue);
0151     bool testAndSetRelease(T *expectedValue, T *newValue);
0152     bool testAndSetOrdered(T *expectedValue, T *newValue);
0153 
0154     static constexpr bool isFetchAndStoreNative();
0155     static constexpr bool isFetchAndStoreWaitFree();
0156 
0157     T *fetchAndStoreRelaxed(T *newValue);
0158     T *fetchAndStoreAcquire(T *newValue);
0159     T *fetchAndStoreRelease(T *newValue);
0160     T *fetchAndStoreOrdered(T *newValue);
0161 
0162     static constexpr bool isFetchAndAddNative();
0163     static constexpr bool isFetchAndAddWaitFree();
0164 
0165     T *fetchAndAddRelaxed(qptrdiff valueToAdd);
0166     T *fetchAndAddAcquire(qptrdiff valueToAdd);
0167     T *fetchAndAddRelease(qptrdiff valueToAdd);
0168     T *fetchAndAddOrdered(qptrdiff valueToAdd);
0169 #endif
0170 };
0171 
0172 QT_WARNING_POP
0173 
0174 /*!
0175     This is a helper for the assignment operators of implicitly
0176     shared classes. Your assignment operator should look like this:
0177 
0178     \snippet code/src.corelib.thread.qatomic.h 0
0179 */
0180 template <typename T>
0181 inline void qAtomicAssign(T *&d, T *x)
0182 {
0183     if (d == x)
0184         return;
0185     x->ref.ref();
0186     if (!d->ref.deref())
0187         delete d;
0188     d = x;
0189 }
0190 
0191 /*!
0192     This is a helper for the detach method of implicitly shared
0193     classes. Your private class needs a copy constructor which copies
0194     the members and sets the refcount to 1. After that, your detach
0195     function should look like this:
0196 
0197     \snippet code/src.corelib.thread.qatomic.h 1
0198 */
0199 template <typename T>
0200 inline void qAtomicDetach(T *&d)
0201 {
0202     if (d->ref.loadRelaxed() == 1)
0203         return;
0204     T *x = d;
0205     d = new T(*d);
0206     if (!x->ref.deref())
0207         delete x;
0208 }
0209 
0210 QT_END_NAMESPACE
0211 #endif // QATOMIC_H