From 2cf466312bce5fcb48d620c98ca81b2c1a40f674 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 31 Jul 2011 19:41:18 -0300 Subject: [PATCH] Unit-test the additional QBasicAtomicXXX expansions Test that they do expand properly and don't produce errors. This is templated code, so it doesn't get tested fully unless we instantiate them. Also check that the alignments are correct. Change-Id: I2a8ee2165167f54b652b4227411e209850974b8e Reviewed-by: Bradley T. Hughes --- .../thread/qatomicint/tst_qatomicint.cpp | 138 +++++++++++++++--- .../qatomicpointer/tst_qatomicpointer.cpp | 10 ++ 2 files changed, 128 insertions(+), 20 deletions(-) diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp index a6d38ca078..c2dc8a4cc6 100644 --- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp @@ -52,6 +52,7 @@ class tst_QAtomicInt : public QObject private slots: void warningFree(); + void alignment(); // QAtomicInt members void constructor_data(); @@ -92,33 +93,101 @@ private: static void warningFreeHelper(); }; +template +static inline void assemblyMarker(void *ptr = 0) +{ + puts((char *)ptr + I); +} + +QT_BEGIN_NAMESPACE +template class QBasicAtomicInteger; // even if it this class isn't supported +QT_END_NAMESPACE + +template +static void warningFreeHelperTemplate() +{ + T expectedValue = 0; + T newValue = 0; + T valueToAdd = 0; + + // the marker calls are here only to provide a divider for + // those reading the assembly output + assemblyMarker<0>(); + Atomic i = Q_BASIC_ATOMIC_INITIALIZER(0); + printf("%d\n", int(i.loadAcquire())); + assemblyMarker<1>(&i); + + // the loads sometimes generate no assembly output + i.load(); + assemblyMarker<11>(&i); + i.loadAcquire(); + assemblyMarker<12>(&i); + + i.store(newValue); + assemblyMarker<21>(&i); + i.storeRelease(newValue); + assemblyMarker<22>(&i); + + i.ref(); + assemblyMarker<31>(&i); + i.deref(); + assemblyMarker<32>(&i); + + i.testAndSetRelaxed(expectedValue, newValue); + assemblyMarker<41>(&i); + i.testAndSetAcquire(expectedValue, newValue); + assemblyMarker<42>(&i); + i.testAndSetRelease(expectedValue, newValue); + assemblyMarker<43>(&i); + i.testAndSetOrdered(expectedValue, newValue); + assemblyMarker<44>(&i); + + i.fetchAndStoreRelaxed(newValue); + assemblyMarker<51>(&i); + i.fetchAndStoreAcquire(newValue); + assemblyMarker<52>(&i); + i.fetchAndStoreRelease(newValue); + assemblyMarker<53>(&i); + i.fetchAndStoreOrdered(newValue); + assemblyMarker<54>(&i); + + i.fetchAndAddRelaxed(valueToAdd); + assemblyMarker<61>(&i); + i.fetchAndAddAcquire(valueToAdd); + assemblyMarker<62>(&i); + i.fetchAndAddRelease(valueToAdd); + assemblyMarker<63>(&i); + i.fetchAndAddOrdered(valueToAdd); + assemblyMarker<64>(&i); +} + void tst_QAtomicInt::warningFreeHelper() { qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); + warningFreeHelperTemplate(); - QBasicAtomicInt i = Q_BASIC_ATOMIC_INITIALIZER(0); +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif - int expectedValue = 0; - int newValue = 0; - int valueToAdd = 0; +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif - i.ref(); - i.deref(); +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif - i.testAndSetRelaxed(expectedValue, newValue); - i.testAndSetAcquire(expectedValue, newValue); - i.testAndSetRelease(expectedValue, newValue); - i.testAndSetOrdered(expectedValue, newValue); - - i.fetchAndStoreRelaxed(newValue); - i.fetchAndStoreAcquire(newValue); - i.fetchAndStoreRelease(newValue); - i.fetchAndStoreOrdered(newValue); - - i.fetchAndAddRelaxed(valueToAdd); - i.fetchAndAddAcquire(valueToAdd); - i.fetchAndAddRelease(valueToAdd); - i.fetchAndAddOrdered(valueToAdd); +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED +#if !defined(__i386__) || (defined(Q_CC_GNU) && defined(__OPTIMIZE__)) + warningFreeHelperTemplate >(); + warningFreeHelperTemplate >(); +#endif +#endif } void tst_QAtomicInt::warningFree() @@ -130,6 +199,35 @@ void tst_QAtomicInt::warningFree() (void)foo; } +template struct TypeInStruct { T type; }; + +void tst_QAtomicInt::alignment() +{ +#ifdef Q_ALIGNOF + // this will cause a build error if the alignment isn't the same + char dummy1[Q_ALIGNOF(QBasicAtomicInt) == Q_ALIGNOF(TypeInStruct) ? 1 : -1]; + char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct) ? 1 : -1]; + (void)dummy1; (void)dummy2; + +#ifdef Q_ATOMIC_INT32_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED + QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger), Q_ALIGNOF(TypeInStruct)); +#endif + +#endif +} + void tst_QAtomicInt::constructor_data() { QTest::addColumn("value"); diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp index a8f7e037d0..ee6460d35c 100644 --- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp @@ -49,6 +49,7 @@ class tst_QAtomicPointer : public QObject Q_OBJECT private slots: void warningFree(); + void alignment(); void constructor(); void copy_constructor(); @@ -114,6 +115,15 @@ void tst_QAtomicPointer::warningFree() (void)foo; } +void tst_QAtomicPointer::alignment() +{ +#ifdef Q_ALIGNOF + // this will cause a build error if the alignment isn't the same + char dummy[Q_ALIGNOF(QBasicAtomicPointer) == Q_ALIGNOF(void*) ? 1 : -1]; + (void)dummy; +#endif +} + void tst_QAtomicPointer::constructor() { void *one = this;