Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:16

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