diff options
Diffstat (limited to 'tests/auto/corelib/tools')
-rw-r--r-- | tests/auto/corelib/tools/qvector/tst_qvector.cpp | 279 |
1 files changed, 178 insertions, 101 deletions
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 7c1e22689e..7738a2c797 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -40,6 +40,9 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include <QAtomicInt> +#include <QThread> +#include <QSemaphore> #include <qvector.h> struct Movable { @@ -47,21 +50,21 @@ struct Movable { : i(input) , state(Constructed) { - ++counter; + counter.fetchAndAddRelaxed(1); } Movable(const Movable &other) : i(other.i) , state(Constructed) { check(other.state, Constructed); - ++counter; + counter.fetchAndAddRelaxed(1); } ~Movable() { check(state, Constructed); i = 0; - --counter; + counter.fetchAndAddRelaxed(-1); state = Destructed; } @@ -80,7 +83,7 @@ struct Movable { return *this; } char i; - static int counter; + static QAtomicInt counter; private: enum State { Constructed = 106, Destructed = 110 }; State state; @@ -91,7 +94,7 @@ private: } }; -int Movable::counter = 0; +QAtomicInt Movable::counter = 0; QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); QT_END_NAMESPACE @@ -103,21 +106,21 @@ struct Custom { , that(this) , state(Constructed) { - ++counter; + counter.fetchAndAddRelaxed(1); } Custom(const Custom &other) : that(this) , state(Constructed) { check(&other); - ++counter; + counter.fetchAndAddRelaxed(1); this->i = other.i; } ~Custom() { check(this); i = 0; - --counter; + counter.fetchAndAddRelaxed(-1); state = Destructed; } @@ -135,7 +138,7 @@ struct Custom { i = other.i; return *this; } - static int counter; + static QAtomicInt counter; char i; // used to identify orgin of an instance private: @@ -151,7 +154,7 @@ private: QCOMPARE(c->state, Constructed); } }; -int Custom::counter = 0; +QAtomicInt Custom::counter = 0; Q_DECLARE_METATYPE(Custom); @@ -271,6 +274,9 @@ private slots: void detachInt() const; void detachMovable() const; void detachCustom() const; + void detachThreadSafetyInt() const; + void detachThreadSafetyMovable() const; + void detachThreadSafetyCustom() const; private: template<typename T> void copyConstructor() const; @@ -294,6 +300,7 @@ private: template<typename T> void setSharable_data() const; template<typename T> void setSharable() const; template<typename T> void detach() const; + template<typename T> void detachThreadSafety() const; }; @@ -415,16 +422,16 @@ void tst_QVector::copyConstructorInt() const void tst_QVector::copyConstructorMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); copyConstructor<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::copyConstructorCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); copyConstructor<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -465,16 +472,16 @@ void tst_QVector::addInt() const void tst_QVector::addMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); add<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::addCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); add<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -523,16 +530,16 @@ void tst_QVector::appendInt() const void tst_QVector::appendMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); append<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::appendCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); append<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::at() const @@ -602,16 +609,16 @@ void tst_QVector::capacityInt() const void tst_QVector::capacityMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); capacity<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::capacityCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); capacity<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -633,16 +640,16 @@ void tst_QVector::clearInt() const void tst_QVector::clearMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); clear<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::clearCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); clear<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::constData() const @@ -717,16 +724,16 @@ void tst_QVector::countInt() const void tst_QVector::countMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); count<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::countCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); count<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::data() const @@ -771,16 +778,16 @@ void tst_QVector::emptyInt() const void tst_QVector::emptyMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); empty<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::emptyCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); empty<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::endsWith() const @@ -826,16 +833,16 @@ void tst_QVector::eraseEmptyInt() const void tst_QVector::eraseEmptyMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); eraseEmpty<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::eraseEmptyCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); eraseEmpty<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -863,16 +870,16 @@ void tst_QVector::eraseEmptyReservedInt() const void tst_QVector::eraseEmptyReservedMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); eraseEmptyReserved<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::eraseEmptyReservedCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); eraseEmptyReserved<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -986,30 +993,30 @@ void tst_QVector::eraseIntShared() const void tst_QVector::eraseMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); erase<Movable>(false); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::eraseMovableShared() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); erase<Movable>(true); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::eraseCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); erase<Custom>(false); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::eraseCustomShared() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); erase<Custom>(true); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> void tst_QVector::eraseReserved() const @@ -1062,16 +1069,16 @@ void tst_QVector::eraseReservedInt() const void tst_QVector::eraseReservedMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); eraseReserved<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::eraseReservedCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); eraseReserved<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -1102,16 +1109,16 @@ void tst_QVector::fillInt() const void tst_QVector::fillMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); fill<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::fillCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); fill<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::first() const @@ -1152,16 +1159,16 @@ void tst_QVector::fromListInt() const void tst_QVector::fromListMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); fromList<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::fromListCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); fromList<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::fromStdVector() const @@ -1338,16 +1345,16 @@ void tst_QVector::prependInt() const void tst_QVector::prependMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); prepend<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::prependCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); prepend<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -1374,16 +1381,16 @@ void tst_QVector::removeInt() const void tst_QVector::removeMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); remove<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::removeCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); remove<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::resizePOD_data() const @@ -1510,7 +1517,7 @@ void tst_QVector::resizeComplexMovable_data() const void tst_QVector::resizeComplexMovable() const { - const int items = Movable::counter; + const int items = Movable::counter.loadAcquire(); { QFETCH(QVector<Movable>, vector); QFETCH(int, size); @@ -1529,7 +1536,7 @@ void tst_QVector::resizeComplexMovable() const QCOMPARE(vector.size(), 0); QVERIFY(vector.capacity() <= capacity); } - QCOMPARE(items, Movable::counter); + QCOMPARE(items, Movable::counter.loadAcquire()); } void tst_QVector::resizeComplex_data() const @@ -1585,7 +1592,7 @@ void tst_QVector::resizeComplex_data() const void tst_QVector::resizeComplex() const { - const int items = Custom::counter; + const int items = Custom::counter.loadAcquire(); { QFETCH(QVector<Custom>, vector); QFETCH(int, size); @@ -1604,12 +1611,12 @@ void tst_QVector::resizeComplex() const QVERIFY(vector.isEmpty()); QVERIFY(vector.capacity() <= capacity); } - QCOMPARE(Custom::counter, items); + QCOMPARE(Custom::counter.loadAcquire(), items); } void tst_QVector::resizeCtorAndDtor() const { - const int items = Custom::counter; + const int items = Custom::counter.loadAcquire(); { QVector<Custom> null; QVector<Custom> empty(0, '0'); @@ -1631,7 +1638,7 @@ void tst_QVector::resizeCtorAndDtor() const nonEmpty.resize(0); nonEmptyReserved.resize(2); } - QCOMPARE(Custom::counter, items); + QCOMPARE(Custom::counter.loadAcquire(), items); } template<typename T> @@ -1661,16 +1668,16 @@ void tst_QVector::sizeInt() const void tst_QVector::sizeMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); size<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::sizeCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); size<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } // ::squeeze() is tested in ::capacity(). @@ -1720,16 +1727,16 @@ void tst_QVector::swapInt() const void tst_QVector::swapMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); swap<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::swapCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); swap<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::toList() const @@ -1947,16 +1954,16 @@ void tst_QVector::initializeListInt() void tst_QVector::initializeListMovable() { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); initializeList<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::initializeListCustom() { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); initializeList<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } void tst_QVector::const_shared_null() @@ -2084,16 +2091,16 @@ void tst_QVector::setSharableInt() void tst_QVector::setSharableMovable() { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); setSharable<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::setSharableCustom() { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); setSharable<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } template<typename T> @@ -2200,17 +2207,87 @@ void tst_QVector::detachInt() const void tst_QVector::detachMovable() const { - const int instancesCount = Movable::counter; + const int instancesCount = Movable::counter.loadAcquire(); detach<Movable>(); - QCOMPARE(instancesCount, Movable::counter); + QCOMPARE(instancesCount, Movable::counter.loadAcquire()); } void tst_QVector::detachCustom() const { - const int instancesCount = Custom::counter; + const int instancesCount = Custom::counter.loadAcquire(); detach<Custom>(); - QCOMPARE(instancesCount, Custom::counter); + QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } -QTEST_APPLESS_MAIN(tst_QVector) +static QAtomicPointer<QVector<int> > detachThreadSafetyDataInt; +static QAtomicPointer<QVector<Movable> > detachThreadSafetyDataMovable; +static QAtomicPointer<QVector<Custom> > detachThreadSafetyDataCustom; + +template<typename T> QAtomicPointer<QVector<T> > *detachThreadSafetyData(); +template<> QAtomicPointer<QVector<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; } +template<> QAtomicPointer<QVector<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; } +template<> QAtomicPointer<QVector<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; } + +static QSemaphore detachThreadSafetyLock; + +template<typename T> +void tst_QVector::detachThreadSafety() const +{ + delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QVector<T>(SimpleValue<T>::vector(400))); + + static const uint threadsCount = 5; + + struct : QThread { + void run() Q_DECL_OVERRIDE + { + QVector<T> copy(*detachThreadSafetyData<T>()->load()); + QVERIFY(!copy.isDetached()); + detachThreadSafetyLock.release(); + detachThreadSafetyLock.acquire(100); + copy.detach(); + } + } threads[threadsCount]; + + for (uint i = 0; i < threadsCount; ++i) + threads[i].start(); + QThread::yieldCurrentThread(); + detachThreadSafetyLock.acquire(threadsCount); + + // destroy static original data + delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0); + + QVERIFY(threadsCount < 100); + detachThreadSafetyLock.release(threadsCount * 100); + QThread::yieldCurrentThread(); + + for (uint i = 0; i < threadsCount; ++i) + threads[i].wait(); +} + +void tst_QVector::detachThreadSafetyInt() const +{ + for (uint i = 0; i < 128; ++i) + detachThreadSafety<int>(); +} + +void tst_QVector::detachThreadSafetyMovable() const +{ + const int instancesCount = Movable::counter.loadAcquire(); + for (uint i = 0; i < 128; ++i) { + detachThreadSafety<Movable>(); + QCOMPARE(Movable::counter.loadAcquire(), instancesCount); + } +} + +void tst_QVector::detachThreadSafetyCustom() const +{ + const int instancesCount = Custom::counter.loadAcquire(); + for (uint i = 0; i < 128; ++i) { + detachThreadSafety<Custom>(); + QCOMPARE(Custom::counter.loadAcquire(), instancesCount); + } +} + + +QTEST_MAIN(tst_QVector) #include "tst_qvector.moc" |