Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/QtCore/qbasicatomic.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
0002 // Copyright (C) 2018 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 QBASICATOMIC_H
0007 #define QBASICATOMIC_H
0008 
0009 #include <QtCore/qatomic_cxx11.h>
0010 
0011 QT_WARNING_PUSH
0012 QT_WARNING_DISABLE_MSVC(4522)
0013 
0014 QT_BEGIN_NAMESPACE
0015 
0016 #if 0
0017 // silence syncqt warnings
0018 QT_END_NAMESPACE
0019 #pragma qt_no_master_include
0020 #pragma qt_sync_stop_processing
0021 #endif
0022 
0023 template <typename T>
0024 class QBasicAtomicInteger
0025 {
0026     // atomic operations must never cause UB, so do signed add/sub in unsigned space:
0027     static T add_no_UB(T lhs, T rhs)
0028     {
0029         using U = std::make_unsigned_t<T>;
0030         return T(U(lhs) + U(rhs));
0031     }
0032     static T sub_no_UB(T lhs, T rhs)
0033     {
0034         using U = std::make_unsigned_t<T>;
0035         return T(U(lhs) - U(rhs));
0036     }
0037 public:
0038     typedef T Type;
0039     typedef QAtomicOps<T> Ops;
0040     // static check that this is a valid integer
0041     static_assert(std::is_integral_v<T>, "template parameter is not an integral type");
0042     static_assert(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
0043 
0044     typename Ops::Type _q_value;
0045 
0046     // Everything below is either implemented in ../arch/qatomic_XXX.h or (as
0047     // fallback) in qgenericatomic.h
0048     T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
0049     void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
0050 
0051     T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
0052     void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
0053     operator T() const noexcept { return loadAcquire(); }
0054     T operator=(T newValue) noexcept { storeRelease(newValue); return newValue; }
0055 
0056     static constexpr bool isReferenceCountingNative() noexcept { return Ops::isReferenceCountingNative(); }
0057     static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); }
0058 
0059     bool ref() noexcept { return Ops::ref(_q_value); }
0060     void refRelaxed() noexcept { Ops::fetchAndAddRelaxed(_q_value, 1); }
0061     bool deref() noexcept { return Ops::deref(_q_value); }
0062 
0063     static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
0064     static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
0065 
0066     bool testAndSetRelaxed(T expectedValue, T newValue) noexcept
0067     { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
0068     bool testAndSetAcquire(T expectedValue, T newValue) noexcept
0069     { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
0070     bool testAndSetRelease(T expectedValue, T newValue) noexcept
0071     { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
0072     bool testAndSetOrdered(T expectedValue, T newValue) noexcept
0073     { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
0074 
0075     bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue) noexcept
0076     { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
0077     bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue) noexcept
0078     { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
0079     bool testAndSetRelease(T expectedValue, T newValue, T &currentValue) noexcept
0080     { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
0081     bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue) noexcept
0082     { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
0083 
0084     static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
0085     static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
0086 
0087     T fetchAndStoreRelaxed(T newValue) noexcept
0088     { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
0089     T fetchAndStoreAcquire(T newValue) noexcept
0090     { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
0091     T fetchAndStoreRelease(T newValue) noexcept
0092     { return Ops::fetchAndStoreRelease(_q_value, newValue); }
0093     T fetchAndStoreOrdered(T newValue) noexcept
0094     { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
0095 
0096     static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
0097     static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
0098 
0099     T fetchAndAddRelaxed(T valueToAdd) noexcept
0100     { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
0101     T fetchAndAddAcquire(T valueToAdd) noexcept
0102     { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
0103     T fetchAndAddRelease(T valueToAdd) noexcept
0104     { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
0105     T fetchAndAddOrdered(T valueToAdd) noexcept
0106     { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
0107 
0108     T fetchAndSubRelaxed(T valueToAdd) noexcept
0109     { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
0110     T fetchAndSubAcquire(T valueToAdd) noexcept
0111     { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
0112     T fetchAndSubRelease(T valueToAdd) noexcept
0113     { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
0114     T fetchAndSubOrdered(T valueToAdd) noexcept
0115     { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
0116 
0117     T fetchAndAndRelaxed(T valueToAdd) noexcept
0118     { return Ops::fetchAndAndRelaxed(_q_value, valueToAdd); }
0119     T fetchAndAndAcquire(T valueToAdd) noexcept
0120     { return Ops::fetchAndAndAcquire(_q_value, valueToAdd); }
0121     T fetchAndAndRelease(T valueToAdd) noexcept
0122     { return Ops::fetchAndAndRelease(_q_value, valueToAdd); }
0123     T fetchAndAndOrdered(T valueToAdd) noexcept
0124     { return Ops::fetchAndAndOrdered(_q_value, valueToAdd); }
0125 
0126     T fetchAndOrRelaxed(T valueToAdd) noexcept
0127     { return Ops::fetchAndOrRelaxed(_q_value, valueToAdd); }
0128     T fetchAndOrAcquire(T valueToAdd) noexcept
0129     { return Ops::fetchAndOrAcquire(_q_value, valueToAdd); }
0130     T fetchAndOrRelease(T valueToAdd) noexcept
0131     { return Ops::fetchAndOrRelease(_q_value, valueToAdd); }
0132     T fetchAndOrOrdered(T valueToAdd) noexcept
0133     { return Ops::fetchAndOrOrdered(_q_value, valueToAdd); }
0134 
0135     T fetchAndXorRelaxed(T valueToAdd) noexcept
0136     { return Ops::fetchAndXorRelaxed(_q_value, valueToAdd); }
0137     T fetchAndXorAcquire(T valueToAdd) noexcept
0138     { return Ops::fetchAndXorAcquire(_q_value, valueToAdd); }
0139     T fetchAndXorRelease(T valueToAdd) noexcept
0140     { return Ops::fetchAndXorRelease(_q_value, valueToAdd); }
0141     T fetchAndXorOrdered(T valueToAdd) noexcept
0142     { return Ops::fetchAndXorOrdered(_q_value, valueToAdd); }
0143 
0144     T operator++() noexcept
0145     { return add_no_UB(fetchAndAddOrdered(1), 1); }
0146     T operator++(int) noexcept
0147     { return fetchAndAddOrdered(1); }
0148     T operator--() noexcept
0149     { return sub_no_UB(fetchAndSubOrdered(1), 1); }
0150     T operator--(int) noexcept
0151     { return fetchAndSubOrdered(1); }
0152 
0153     T operator+=(T v) noexcept
0154     { return add_no_UB(fetchAndAddOrdered(v), v); }
0155     T operator-=(T v) noexcept
0156     { return sub_no_UB(fetchAndSubOrdered(v), v); }
0157     T operator&=(T v) noexcept
0158     { return fetchAndAndOrdered(v) & v; }
0159     T operator|=(T v) noexcept
0160     { return fetchAndOrOrdered(v) | v; }
0161     T operator^=(T v) noexcept
0162     { return fetchAndXorOrdered(v) ^ v; }
0163 
0164 
0165     QBasicAtomicInteger() = default;
0166     constexpr QBasicAtomicInteger(T value) noexcept : _q_value(value) {}
0167     QBasicAtomicInteger(const QBasicAtomicInteger &) = delete;
0168     QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete;
0169     QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete;
0170 };
0171 typedef QBasicAtomicInteger<int> QBasicAtomicInt;
0172 
0173 template <typename X>
0174 class QBasicAtomicPointer
0175 {
0176 public:
0177     typedef X *Type;
0178     typedef QAtomicOps<Type> Ops;
0179     typedef typename Ops::Type AtomicType;
0180 
0181     AtomicType _q_value;
0182 
0183     Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
0184     void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
0185 
0186     operator Type() const noexcept { return loadAcquire(); }
0187     Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; }
0188 
0189     // Atomic API, implemented in qatomic_XXX.h
0190     Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
0191     void storeRelease(Type newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
0192 
0193     static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
0194     static constexpr bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
0195 
0196     bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept
0197     { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
0198     bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept
0199     { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
0200     bool testAndSetRelease(Type expectedValue, Type newValue) noexcept
0201     { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
0202     bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept
0203     { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
0204 
0205     bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) noexcept
0206     { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
0207     bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) noexcept
0208     { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
0209     bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) noexcept
0210     { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
0211     bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) noexcept
0212     { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
0213 
0214     static constexpr bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
0215     static constexpr bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
0216 
0217     Type fetchAndStoreRelaxed(Type newValue) noexcept
0218     { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
0219     Type fetchAndStoreAcquire(Type newValue) noexcept
0220     { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
0221     Type fetchAndStoreRelease(Type newValue) noexcept
0222     { return Ops::fetchAndStoreRelease(_q_value, newValue); }
0223     Type fetchAndStoreOrdered(Type newValue) noexcept
0224     { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
0225 
0226     static constexpr bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
0227     static constexpr bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
0228 
0229     Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept
0230     { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
0231     Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept
0232     { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
0233     Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept
0234     { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
0235     Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept
0236     { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
0237 
0238     Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept
0239     { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
0240     Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept
0241     { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
0242     Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept
0243     { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
0244     Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept
0245     { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
0246 
0247     Type operator++() noexcept
0248     { return fetchAndAddOrdered(1) + 1; }
0249     Type operator++(int) noexcept
0250     { return fetchAndAddOrdered(1); }
0251     Type operator--() noexcept
0252     { return fetchAndSubOrdered(1) - 1; }
0253     Type operator--(int) noexcept
0254     { return fetchAndSubOrdered(1); }
0255     Type operator+=(qptrdiff valueToAdd) noexcept
0256     { return fetchAndAddOrdered(valueToAdd) + valueToAdd; }
0257     Type operator-=(qptrdiff valueToSub) noexcept
0258     { return fetchAndSubOrdered(valueToSub) - valueToSub; }
0259 
0260     QBasicAtomicPointer() = default;
0261     constexpr QBasicAtomicPointer(Type value) noexcept : _q_value(value) {}
0262     QBasicAtomicPointer(const QBasicAtomicPointer &) = delete;
0263     QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) = delete;
0264     QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) volatile = delete;
0265 };
0266 
0267 #ifndef Q_BASIC_ATOMIC_INITIALIZER
0268 #  define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }
0269 #endif
0270 
0271 QT_END_NAMESPACE
0272 
0273 QT_WARNING_POP
0274 
0275 #endif // QBASICATOMIC_H