Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-01 09:17:23

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     void refRelaxed();
0050     bool deref();
0051 
0052     static constexpr bool isTestAndSetNative();
0053     static constexpr bool isTestAndSetWaitFree();
0054 
0055     bool testAndSetRelaxed(T expectedValue, T newValue);
0056     bool testAndSetAcquire(T expectedValue, T newValue);
0057     bool testAndSetRelease(T expectedValue, T newValue);
0058     bool testAndSetOrdered(T expectedValue, T newValue);
0059 
0060     bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue);
0061     bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue);
0062     bool testAndSetRelease(T expectedValue, T newValue, T &currentValue);
0063     bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue);
0064 
0065     static constexpr bool isFetchAndStoreNative();
0066     static constexpr bool isFetchAndStoreWaitFree();
0067 
0068     T fetchAndStoreRelaxed(T newValue);
0069     T fetchAndStoreAcquire(T newValue);
0070     T fetchAndStoreRelease(T newValue);
0071     T fetchAndStoreOrdered(T newValue);
0072 
0073     static constexpr bool isFetchAndAddNative();
0074     static constexpr bool isFetchAndAddWaitFree();
0075 
0076     T fetchAndAddRelaxed(T valueToAdd);
0077     T fetchAndAddAcquire(T valueToAdd);
0078     T fetchAndAddRelease(T valueToAdd);
0079     T fetchAndAddOrdered(T valueToAdd);
0080 
0081     T fetchAndSubRelaxed(T valueToSub);
0082     T fetchAndSubAcquire(T valueToSub);
0083     T fetchAndSubRelease(T valueToSub);
0084     T fetchAndSubOrdered(T valueToSub);
0085 
0086     T fetchAndOrRelaxed(T valueToOr);
0087     T fetchAndOrAcquire(T valueToOr);
0088     T fetchAndOrRelease(T valueToOr);
0089     T fetchAndOrOrdered(T valueToOr);
0090 
0091     T fetchAndAndRelaxed(T valueToAnd);
0092     T fetchAndAndAcquire(T valueToAnd);
0093     T fetchAndAndRelease(T valueToAnd);
0094     T fetchAndAndOrdered(T valueToAnd);
0095 
0096     T fetchAndXorRelaxed(T valueToXor);
0097     T fetchAndXorAcquire(T valueToXor);
0098     T fetchAndXorRelease(T valueToXor);
0099     T fetchAndXorOrdered(T valueToXor);
0100 
0101     T operator++();
0102     T operator++(int);
0103     T operator--();
0104     T operator--(int);
0105     T operator+=(T value);
0106     T operator-=(T value);
0107     T operator|=(T value);
0108     T operator&=(T value);
0109     T operator^=(T value);
0110 #endif
0111 };
0112 
0113 class QAtomicInt : public QAtomicInteger<int>
0114 {
0115 public:
0116     // Non-atomic API
0117     // We could use QT_COMPILER_INHERITING_CONSTRUCTORS, but we need only one;
0118     // the implicit definition for all the others is fine.
0119     constexpr QAtomicInt(int value = 0) noexcept : QAtomicInteger<int>(value) {}
0120 };
0121 
0122 // High-level atomic pointer operations
0123 template <typename T>
0124 class QAtomicPointer : public QBasicAtomicPointer<T>
0125 {
0126 public:
0127     constexpr QAtomicPointer(T *value = nullptr) noexcept : QBasicAtomicPointer<T>(value) {}
0128 
0129     inline QAtomicPointer(const QAtomicPointer<T> &other) noexcept
0130         : QBasicAtomicPointer<T>()
0131     {
0132         this->storeRelease(other.loadAcquire());
0133     }
0134 
0135     inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) noexcept
0136     {
0137         this->storeRelease(other.loadAcquire());
0138         return *this;
0139     }
0140 
0141 #ifdef Q_QDOC
0142     T *loadAcquire() const;
0143     T *loadRelaxed() const;
0144     void storeRelaxed(T *newValue);
0145     void storeRelease(T *newValue);
0146 
0147     static constexpr bool isTestAndSetNative();
0148     static constexpr bool isTestAndSetWaitFree();
0149 
0150     bool testAndSetRelaxed(T *expectedValue, T *newValue);
0151     bool testAndSetAcquire(T *expectedValue, T *newValue);
0152     bool testAndSetRelease(T *expectedValue, T *newValue);
0153     bool testAndSetOrdered(T *expectedValue, T *newValue);
0154 
0155     bool testAndSetRelaxed(T *expectedValue, T *newValue, T *&currentValue);
0156     bool testAndSetAcquire(T *expectedValue, T *newValue, T *&currentValue);
0157     bool testAndSetRelease(T *expectedValue, T *newValue, T *&currentValue);
0158     bool testAndSetOrdered(T *expectedValue, T *newValue, T *&currentValue);
0159 
0160     static constexpr bool isFetchAndStoreNative();
0161     static constexpr bool isFetchAndStoreWaitFree();
0162 
0163     T *fetchAndStoreRelaxed(T *newValue);
0164     T *fetchAndStoreAcquire(T *newValue);
0165     T *fetchAndStoreRelease(T *newValue);
0166     T *fetchAndStoreOrdered(T *newValue);
0167 
0168     static constexpr bool isFetchAndAddNative();
0169     static constexpr bool isFetchAndAddWaitFree();
0170 
0171     T *fetchAndAddRelaxed(qptrdiff valueToAdd);
0172     T *fetchAndAddAcquire(qptrdiff valueToAdd);
0173     T *fetchAndAddRelease(qptrdiff valueToAdd);
0174     T *fetchAndAddOrdered(qptrdiff valueToAdd);
0175 #endif
0176 };
0177 
0178 QT_WARNING_POP
0179 
0180 /*!
0181     This is a helper for the assignment operators of implicitly
0182     shared classes. Your assignment operator should look like this:
0183 
0184     \snippet code/src.corelib.thread.qatomic.h 0
0185 */
0186 template <typename T>
0187 inline void qAtomicAssign(T *&d, T *x)
0188 {
0189     if (d == x)
0190         return;
0191     x->ref.ref();
0192     if (!d->ref.deref())
0193         delete d;
0194     d = x;
0195 }
0196 
0197 /*!
0198     This is a helper for the detach method of implicitly shared
0199     classes. Your private class needs a copy constructor which copies
0200     the members and sets the refcount to 1. After that, your detach
0201     function should look like this:
0202 
0203     \snippet code/src.corelib.thread.qatomic.h 1
0204 */
0205 template <typename T>
0206 inline void qAtomicDetach(T *&d)
0207 {
0208     if (d->ref.loadRelaxed() == 1)
0209         return;
0210     T *x = d;
0211     d = new T(*d);
0212     if (!x->ref.deref())
0213         delete x;
0214 }
0215 
0216 QT_END_NAMESPACE
0217 #endif // QATOMIC_H