File indexing completed on 2025-01-18 10:07:16
0001
0002
0003
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
0016 template <typename T>
0017 class QAtomicInteger : public QBasicAtomicInteger<T>
0018 {
0019 public:
0020
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 ¤tValue);
0059 bool testAndSetAcquire(T expectedValue, T newValue, T ¤tValue);
0060 bool testAndSetRelease(T expectedValue, T newValue, T ¤tValue);
0061 bool testAndSetOrdered(T expectedValue, T newValue, T ¤tValue);
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
0115
0116
0117 constexpr QAtomicInt(int value = 0) noexcept : QAtomicInteger<int>(value) {}
0118 };
0119
0120
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
0175
0176
0177
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
0192
0193
0194
0195
0196
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