From 9004a2412ba1f9976c2c61f01223dff852208c42 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 18 Aug 2021 11:48:29 +0200 Subject: Standardise layout and naming in corelib benchmarks Make file names match CMake's test names (and those follow dir-name) and class names follow tst_ClassName pattern when testing ClassName. Purge comments about the qmake configs the CMakeLists.txt are generated from. Purge empty constructors and init/cleanup methods of classes. Fix petty coding style violations. Add qdir/tree/, qurl, qbench and qset benchmarks to their parent directories' lists of subdirs. Fix unused return error from qurl benchmark. Change-Id: Ifc15a3a46e71cf82ad0637753517e0df34049763 Reviewed-by: Andrei Golubev Reviewed-by: Thiago Macieira --- .../corelib/thread/qfuture/CMakeLists.txt | 2 +- .../corelib/thread/qfuture/tst_bench_qfuture.cpp | 321 +++++++++++++++ .../corelib/thread/qfuture/tst_qfuture.cpp | 320 --------------- .../corelib/thread/qmutex/CMakeLists.txt | 7 +- .../corelib/thread/qmutex/tst_bench_qmutex.cpp | 454 +++++++++++++++++++++ .../corelib/thread/qmutex/tst_qmutex.cpp | 453 -------------------- .../corelib/thread/qreadwritelock/CMakeLists.txt | 7 +- .../qreadwritelock/tst_bench_qreadwritelock.cpp | 259 ++++++++++++ .../thread/qreadwritelock/tst_qreadwritelock.cpp | 259 ------------ .../corelib/thread/qthreadpool/CMakeLists.txt | 7 +- .../thread/qthreadpool/tst_bench_qthreadpool.cpp | 80 ++++ .../corelib/thread/qthreadpool/tst_qthreadpool.cpp | 79 ---- .../corelib/thread/qthreadstorage/CMakeLists.txt | 7 +- .../qthreadstorage/tst_bench_qthreadstorage.cpp | 109 +++++ .../thread/qthreadstorage/tst_qthreadstorage.cpp | 109 ----- .../corelib/thread/qwaitcondition/CMakeLists.txt | 7 +- .../qwaitcondition/tst_bench_qwaitcondition.cpp | 129 ++++++ .../thread/qwaitcondition/tst_qwaitcondition.cpp | 129 ------ 18 files changed, 1358 insertions(+), 1380 deletions(-) create mode 100644 tests/benchmarks/corelib/thread/qfuture/tst_bench_qfuture.cpp delete mode 100644 tests/benchmarks/corelib/thread/qfuture/tst_qfuture.cpp create mode 100644 tests/benchmarks/corelib/thread/qmutex/tst_bench_qmutex.cpp delete mode 100644 tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp create mode 100644 tests/benchmarks/corelib/thread/qreadwritelock/tst_bench_qreadwritelock.cpp delete mode 100644 tests/benchmarks/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp create mode 100644 tests/benchmarks/corelib/thread/qthreadpool/tst_bench_qthreadpool.cpp delete mode 100644 tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp create mode 100644 tests/benchmarks/corelib/thread/qthreadstorage/tst_bench_qthreadstorage.cpp delete mode 100644 tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp create mode 100644 tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp delete mode 100644 tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp (limited to 'tests/benchmarks/corelib/thread') diff --git a/tests/benchmarks/corelib/thread/qfuture/CMakeLists.txt b/tests/benchmarks/corelib/thread/qfuture/CMakeLists.txt index 4a737c62b8..d53e3f6728 100644 --- a/tests/benchmarks/corelib/thread/qfuture/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qfuture/CMakeLists.txt @@ -5,7 +5,7 @@ qt_internal_add_benchmark(tst_bench_qfuture EXCEPTIONS SOURCES - tst_qfuture.cpp + tst_bench_qfuture.cpp PUBLIC_LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/thread/qfuture/tst_bench_qfuture.cpp b/tests/benchmarks/corelib/thread/qfuture/tst_bench_qfuture.cpp new file mode 100644 index 0000000000..17c2f20712 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qfuture/tst_bench_qfuture.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +class tst_QFuture : public QObject +{ + Q_OBJECT + +private slots: + void makeReadyfuture(); +#ifndef QT_NO_EXCEPTIONS + void makeExceptionalFuture(); +#endif + void result(); + void results(); + void takeResult(); + void reportResult(); + void reportResults(); + void reportResultsManualProgress(); +#ifndef QT_NO_EXCEPTIONS + void reportException(); +#endif + void then(); + void thenVoid(); + void onCanceled(); + void onCanceledVoid(); +#ifndef QT_NO_EXCEPTIONS + void onFailed(); + void onFailedVoid(); + void thenOnFailed(); + void thenOnFailedVoid(); +#endif + void reportProgress(); + void progressMinimum(); + void progressMaximum(); + void progressValue(); + void progressText(); +}; + +void tst_QFuture::makeReadyfuture() +{ + QBENCHMARK { + auto future = QtFuture::makeReadyFuture(42); + Q_UNUSED(future); + } +} + +#ifndef QT_NO_EXCEPTIONS +void tst_QFuture::makeExceptionalFuture() +{ + QException e; + QBENCHMARK { + auto future = QtFuture::makeExceptionalFuture(e); + Q_UNUSED(future); + } +} +#endif + +void tst_QFuture::result() +{ + auto future = QtFuture::makeReadyFuture(42); + + QBENCHMARK { + auto value = future.result(); + Q_UNUSED(value); + } +} + +void tst_QFuture::results() +{ + QFutureInterface fi; + fi.reportStarted(); + + for (int i = 0; i < 1000; ++i) + fi.reportResult(i); + + fi.reportFinished(); + + auto future = fi.future(); + QBENCHMARK { + auto values = future.results(); + Q_UNUSED(values); + } +} + +void tst_QFuture::takeResult() +{ + QBENCHMARK { + auto future = QtFuture::makeReadyFuture(42); + auto value = future.takeResult(); + Q_UNUSED(value); + } +} + +void tst_QFuture::reportResult() +{ + QFutureInterface fi; + QBENCHMARK { + fi.reportResult(42); + } +} + +void tst_QFuture::reportResults() +{ + QFutureInterface fi; + QList values(1000); + std::iota(values.begin(), values.end(), 0); + QBENCHMARK { + fi.reportResults(values); + } +} + +void tst_QFuture::reportResultsManualProgress() +{ + QFutureInterface fi; + const int resultCount = 1000; + fi.setProgressRange(0, resultCount); + QBENCHMARK { + for (int i = 0; i < resultCount; ++i) + fi.reportResult(i); + } +} + +#ifndef QT_NO_EXCEPTIONS +void tst_QFuture::reportException() +{ + QException e; + QBENCHMARK { + QFutureInterface fi; + fi.reportException(e); + } +} +#endif + +void tst_QFuture::then() +{ + auto f = QtFuture::makeReadyFuture(42); + QBENCHMARK { + auto future = f.then([](int value) { return value; }); + Q_UNUSED(future); + } +} + +void tst_QFuture::thenVoid() +{ + auto f = QtFuture::makeReadyFuture(); + QBENCHMARK { + auto future = f.then([] {}); + Q_UNUSED(future); + } +} + +void tst_QFuture::onCanceled() +{ + QFutureInterface fi; + fi.reportStarted(); + fi.reportCanceled(); + fi.reportFinished(); + + QBENCHMARK { + auto future = fi.future().onCanceled([] { return 0; }); + Q_UNUSED(future); + } +} + +void tst_QFuture::onCanceledVoid() +{ + QFutureInterface fi; + fi.reportStarted(); + fi.reportCanceled(); + fi.reportFinished(); + + QBENCHMARK { + auto future = fi.future().onCanceled([] {}); + Q_UNUSED(future); + } +} + +#ifndef QT_NO_EXCEPTIONS +void tst_QFuture::onFailed() +{ + QException e; + auto f = QtFuture::makeExceptionalFuture(e); + QBENCHMARK { + auto future = f.onFailed([] { return 0; }); + Q_UNUSED(future); + } +} + +void tst_QFuture::onFailedVoid() +{ + QException e; + auto f = QtFuture::makeExceptionalFuture(e); + QBENCHMARK { + auto future = f.onFailed([] {}); + Q_UNUSED(future); + } +} + +void tst_QFuture::thenOnFailed() +{ + auto f = QtFuture::makeReadyFuture(42); + QBENCHMARK { + auto future = + f.then([](int) { throw std::runtime_error("error"); }).onFailed([] { return 0; }); + Q_UNUSED(future); + } +} + +void tst_QFuture::thenOnFailedVoid() +{ + auto f = QtFuture::makeReadyFuture(); + QBENCHMARK { + auto future = f.then([] { throw std::runtime_error("error"); }).onFailed([] {}); + Q_UNUSED(future); + } +} + +#endif + +void tst_QFuture::reportProgress() +{ + QFutureInterface fi; + fi.reportStarted(); + fi.reportFinished(); + QBENCHMARK { + for (int i = 0; i < 100; ++i) { + fi.setProgressValue(i); + } + } +} + +void tst_QFuture::progressMinimum() +{ + QFutureInterface fi; + fi.setProgressRange(0, 100); + fi.reportStarted(); + fi.reportFinished(); + auto future = fi.future(); + + QBENCHMARK { + auto value = future.progressMinimum(); + Q_UNUSED(value); + } +} + +void tst_QFuture::progressMaximum() +{ + QFutureInterface fi; + fi.setProgressRange(0, 100); + fi.reportStarted(); + fi.reportFinished(); + auto future = fi.future(); + + QBENCHMARK { + auto value = future.progressMaximum(); + Q_UNUSED(value); + } +} + +void tst_QFuture::progressValue() +{ + QFutureInterface fi; + fi.setProgressValue(50); + fi.reportStarted(); + fi.reportFinished(); + auto future = fi.future(); + + QBENCHMARK { + auto value = future.progressValue(); + Q_UNUSED(value); + } +} + +void tst_QFuture::progressText() +{ + QFutureInterface fi; + fi.setProgressValueAndText(50, "text"); + fi.reportStarted(); + fi.reportFinished(); + auto future = fi.future(); + + QBENCHMARK { + auto text = future.progressText(); + Q_UNUSED(text); + } +} + +QTEST_MAIN(tst_QFuture) + +#include "tst_bench_qfuture.moc" diff --git a/tests/benchmarks/corelib/thread/qfuture/tst_qfuture.cpp b/tests/benchmarks/corelib/thread/qfuture/tst_qfuture.cpp deleted file mode 100644 index c7a4ff24d9..0000000000 --- a/tests/benchmarks/corelib/thread/qfuture/tst_qfuture.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include - -class tst_QFuture : public QObject -{ - Q_OBJECT - -private slots: - void makeReadyfuture(); -#ifndef QT_NO_EXCEPTIONS - void makeExceptionalFuture(); -#endif - void result(); - void results(); - void takeResult(); - void reportResult(); - void reportResults(); - void reportResultsManualProgress(); -#ifndef QT_NO_EXCEPTIONS - void reportException(); -#endif - void then(); - void thenVoid(); - void onCanceled(); - void onCanceledVoid(); -#ifndef QT_NO_EXCEPTIONS - void onFailed(); - void onFailedVoid(); - void thenOnFailed(); - void thenOnFailedVoid(); -#endif - void reportProgress(); - void progressMinimum(); - void progressMaximum(); - void progressValue(); - void progressText(); -}; - -void tst_QFuture::makeReadyfuture() -{ - QBENCHMARK { - auto future = QtFuture::makeReadyFuture(42); - Q_UNUSED(future); - } -} - -#ifndef QT_NO_EXCEPTIONS -void tst_QFuture::makeExceptionalFuture() -{ - QException e; - QBENCHMARK { - auto future = QtFuture::makeExceptionalFuture(e); - Q_UNUSED(future); - } -} -#endif - -void tst_QFuture::result() -{ - auto future = QtFuture::makeReadyFuture(42); - - QBENCHMARK { - auto value = future.result(); - Q_UNUSED(value); - } -} - -void tst_QFuture::results() -{ - QFutureInterface fi; - fi.reportStarted(); - - for (int i = 0; i < 1000; ++i) - fi.reportResult(i); - - fi.reportFinished(); - - auto future = fi.future(); - QBENCHMARK { - auto values = future.results(); - Q_UNUSED(values); - } -} - -void tst_QFuture::takeResult() -{ - QBENCHMARK { - auto future = QtFuture::makeReadyFuture(42); - auto value = future.takeResult(); - Q_UNUSED(value); - } -} - -void tst_QFuture::reportResult() -{ - QFutureInterface fi; - QBENCHMARK { - fi.reportResult(42); - } -} - -void tst_QFuture::reportResults() -{ - QFutureInterface fi; - QList values(1000); - std::iota(values.begin(), values.end(), 0); - QBENCHMARK { - fi.reportResults(values); - } -} - -void tst_QFuture::reportResultsManualProgress() -{ - QFutureInterface fi; - const int resultCount = 1000; - fi.setProgressRange(0, resultCount); - QBENCHMARK { - for (int i = 0; i < resultCount; ++i) - fi.reportResult(i); - } -} - -#ifndef QT_NO_EXCEPTIONS -void tst_QFuture::reportException() -{ - QException e; - QBENCHMARK { - QFutureInterface fi; - fi.reportException(e); - } -} -#endif - -void tst_QFuture::then() -{ - auto f = QtFuture::makeReadyFuture(42); - QBENCHMARK { - auto future = f.then([](int value) { return value; }); - Q_UNUSED(future); - } -} - -void tst_QFuture::thenVoid() -{ - auto f = QtFuture::makeReadyFuture(); - QBENCHMARK { - auto future = f.then([] {}); - Q_UNUSED(future); - } -} - -void tst_QFuture::onCanceled() -{ - QFutureInterface fi; - fi.reportStarted(); - fi.reportCanceled(); - fi.reportFinished(); - - QBENCHMARK { - auto future = fi.future().onCanceled([] { return 0; }); - Q_UNUSED(future); - } -} - -void tst_QFuture::onCanceledVoid() -{ - QFutureInterface fi; - fi.reportStarted(); - fi.reportCanceled(); - fi.reportFinished(); - - QBENCHMARK { - auto future = fi.future().onCanceled([] {}); - Q_UNUSED(future); - } -} - -#ifndef QT_NO_EXCEPTIONS -void tst_QFuture::onFailed() -{ - QException e; - auto f = QtFuture::makeExceptionalFuture(e); - QBENCHMARK { - auto future = f.onFailed([] { return 0; }); - Q_UNUSED(future); - } -} - -void tst_QFuture::onFailedVoid() -{ - QException e; - auto f = QtFuture::makeExceptionalFuture(e); - QBENCHMARK { - auto future = f.onFailed([] {}); - Q_UNUSED(future); - } -} - -void tst_QFuture::thenOnFailed() -{ - auto f = QtFuture::makeReadyFuture(42); - QBENCHMARK { - auto future = - f.then([](int) { throw std::runtime_error("error"); }).onFailed([] { return 0; }); - Q_UNUSED(future); - } -} - -void tst_QFuture::thenOnFailedVoid() -{ - auto f = QtFuture::makeReadyFuture(); - QBENCHMARK { - auto future = f.then([] { throw std::runtime_error("error"); }).onFailed([] {}); - Q_UNUSED(future); - } -} - -#endif - -void tst_QFuture::reportProgress() -{ - QFutureInterface fi; - fi.reportStarted(); - fi.reportFinished(); - QBENCHMARK { - for (int i = 0; i < 100; ++i) { - fi.setProgressValue(i); - } - } -} - -void tst_QFuture::progressMinimum() -{ - QFutureInterface fi; - fi.setProgressRange(0, 100); - fi.reportStarted(); - fi.reportFinished(); - auto future = fi.future(); - - QBENCHMARK { - auto value = future.progressMinimum(); - Q_UNUSED(value); - } -} - -void tst_QFuture::progressMaximum() -{ - QFutureInterface fi; - fi.setProgressRange(0, 100); - fi.reportStarted(); - fi.reportFinished(); - auto future = fi.future(); - - QBENCHMARK { - auto value = future.progressMaximum(); - Q_UNUSED(value); - } -} - -void tst_QFuture::progressValue() -{ - QFutureInterface fi; - fi.setProgressValue(50); - fi.reportStarted(); - fi.reportFinished(); - auto future = fi.future(); - - QBENCHMARK { - auto value = future.progressValue(); - Q_UNUSED(value); - } -} - -void tst_QFuture::progressText() -{ - QFutureInterface fi; - fi.setProgressValueAndText(50, "text"); - fi.reportStarted(); - fi.reportFinished(); - auto future = fi.future(); - - QBENCHMARK { - auto text = future.progressText(); - Q_UNUSED(text); - } -} - -QTEST_MAIN(tst_QFuture) -#include "tst_qfuture.moc" diff --git a/tests/benchmarks/corelib/thread/qmutex/CMakeLists.txt b/tests/benchmarks/corelib/thread/qmutex/CMakeLists.txt index 923bfba117..d056a10568 100644 --- a/tests/benchmarks/corelib/thread/qmutex/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qmutex/CMakeLists.txt @@ -1,16 +1,11 @@ -# Generated from qmutex.pro. - ##################################################################### ## tst_bench_qmutex Binary: ##################################################################### qt_internal_add_benchmark(tst_bench_qmutex SOURCES - tst_qmutex.cpp + tst_bench_qmutex.cpp PUBLIC_LIBRARIES Qt::CorePrivate Qt::Test ) - -#### Keys ignored in scope 1:.:.:qmutex.pro:: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_bench_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_bench_qmutex.cpp new file mode 100644 index 0000000000..987612b7b2 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qmutex/tst_bench_qmutex.cpp @@ -0,0 +1,454 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include + +//#define USE_SEM_T + +#if defined(Q_OS_UNIX) +#if !defined(USE_SEM_T) +# include +# include +typedef pthread_mutex_t NativeMutexType; +void NativeMutexInitialize(NativeMutexType *mutex) +{ + pthread_mutex_init(mutex, NULL); +} +void NativeMutexDestroy(NativeMutexType *mutex) +{ + pthread_mutex_destroy(mutex); +} +void NativeMutexLock(NativeMutexType *mutex) +{ + pthread_mutex_lock(mutex); +} +void NativeMutexUnlock(NativeMutexType *mutex) +{ + pthread_mutex_unlock(mutex); +} +#else +# include +typedef sem_t NativeMutexType; +void NativeMutexInitialize(NativeMutexType *mutex) +{ + sem_init(mutex, false, 1); +} +void NativeMutexDestroy(NativeMutexType *mutex) +{ + sem_destroy(mutex); +} +void NativeMutexLock(NativeMutexType *mutex) +{ + sem_wait(mutex); +} +void NativeMutexUnlock(NativeMutexType *mutex) +{ + sem_post(mutex); +} +#endif +#elif defined(Q_OS_WIN) +# define _WIN32_WINNT 0x0400 +# include +typedef CRITICAL_SECTION NativeMutexType; +void NativeMutexInitialize(NativeMutexType *mutex) +{ + InitializeCriticalSection(mutex); +} +void NativeMutexDestroy(NativeMutexType *mutex) +{ + DeleteCriticalSection(mutex); +} +void NativeMutexLock(NativeMutexType *mutex) +{ + EnterCriticalSection(mutex); +} +void NativeMutexUnlock(NativeMutexType *mutex) +{ + LeaveCriticalSection(mutex); +} +#endif + +class tst_QMutex : public QObject +{ + Q_OBJECT + + int threadCount; + +public: + // barriers for the contended tests + static QSemaphore semaphore1, semaphore2, semaphore3, semaphore4; + + tst_QMutex() + { + // at least 2 threads, even on single cpu/core machines + threadCount = qMax(2, QThread::idealThreadCount()); + qDebug("thread count: %d", threadCount); + } + +private slots: + void noThread_data(); + void noThread(); + + void constructionNative(); + void uncontendedNative(); + void constructionQMutex(); + void uncontendedQMutex(); + void uncontendedQMutexLocker(); + + void contendedNative_data(); + void contendedQMutex_data() { contendedNative_data(); } + void contendedQMutexLocker_data() { contendedNative_data(); } + + void contendedNative(); + void contendedQMutex(); + void contendedQMutexLocker(); +}; + +QSemaphore tst_QMutex::semaphore1; +QSemaphore tst_QMutex::semaphore2; +QSemaphore tst_QMutex::semaphore3; +QSemaphore tst_QMutex::semaphore4; + +void tst_QMutex::noThread_data() +{ + QTest::addColumn("t"); + + QTest::newRow("noLock") << 1; + QTest::newRow("QMutex") << 3; + QTest::newRow("QMutexLocker") << 4; +} + +void tst_QMutex::noThread() +{ + volatile int count = 0; + const int N = 5000000; + QMutex mtx; + + QFETCH(int, t); + switch(t) { + case 1: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + QtPrivate::volatilePreIncrement(count); + } + } + break; + case 3: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + mtx.lock(); + QtPrivate::volatilePreIncrement(count); + mtx.unlock(); + } + } + break; + case 4: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + QMutexLocker locker(&mtx); + QtPrivate::volatilePreIncrement(count); + } + } + break; + } + QCOMPARE(int(count), N); +} + +void tst_QMutex::constructionNative() +{ + QBENCHMARK { + NativeMutexType mutex; + NativeMutexInitialize(&mutex); + NativeMutexDestroy(&mutex); + } +} + +void tst_QMutex::uncontendedNative() +{ + NativeMutexType mutex; + NativeMutexInitialize(&mutex); + QBENCHMARK { + NativeMutexLock(&mutex); + NativeMutexUnlock(&mutex); + } + NativeMutexDestroy(&mutex); +} + +void tst_QMutex::constructionQMutex() +{ + QBENCHMARK { + QMutex mutex; + Q_UNUSED(mutex); + } +} + +void tst_QMutex::uncontendedQMutex() +{ + QMutex mutex; + QBENCHMARK { + mutex.lock(); + mutex.unlock(); + } +} + +void tst_QMutex::uncontendedQMutexLocker() +{ + QMutex mutex; + QBENCHMARK { + QMutexLocker locker(&mutex); + } +} + +void tst_QMutex::contendedNative_data() +{ + QTest::addColumn("iterations"); + QTest::addColumn("msleepDuration"); + QTest::addColumn("use2mutexes"); + + QTest::newRow("baseline") << 0 << -1 << false; + + QTest::newRow("no msleep, 1 mutex") << 1000 << -1 << false; + QTest::newRow("no msleep, 2 mutexes") << 1000 << -1 << true; + QTest::newRow("msleep(0), 1 mutex") << 1000 << 0 << false; + QTest::newRow("msleep(0), 2 mutexes") << 1000 << 0 << true; + QTest::newRow("msleep(1), 1 mutex") << 10 << 1 << false; + QTest::newRow("msleep(1), 2 mutexes") << 10 << 1 << true; + QTest::newRow("msleep(2), 1 mutex") << 10 << 2 << false; + QTest::newRow("msleep(2), 2 mutexes") << 10 << 2 << true; + QTest::newRow("msleep(10), 1 mutex") << 10 << 10 << false; + QTest::newRow("msleep(10), 2 mutexes") << 10 << 10 << true; +} + +class NativeMutexThread : public QThread +{ + NativeMutexType *mutex1, *mutex2; + int iterations, msleepDuration; + bool use2mutexes; +public: + bool done; + NativeMutexThread(NativeMutexType *mutex1, NativeMutexType *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) + { } + void run() override + { + forever { + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + NativeMutexLock(mutex1); + if (use2mutexes) + NativeMutexLock(mutex2); + if (msleepDuration >= 0) + msleep(msleepDuration); + if (use2mutexes) + NativeMutexUnlock(mutex2); + NativeMutexUnlock(mutex1); + + QThread::yieldCurrentThread(); + } + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); + } + } +}; + +void tst_QMutex::contendedNative() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); + + NativeMutexType mutex1, mutex2; + NativeMutexInitialize(&mutex1); + NativeMutexInitialize(&mutex2); + + QList threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new NativeMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); + + NativeMutexDestroy(&mutex1); + NativeMutexDestroy(&mutex2); +} + +class QMutexThread : public QThread +{ + QMutex *mutex1, *mutex2; + int iterations, msleepDuration; + bool use2mutexes; +public: + bool done; + QMutexThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) + { } + void run() override + { + forever { + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + mutex1->lock(); + if (use2mutexes) + mutex2->lock(); + if (msleepDuration >= 0) + msleep(msleepDuration); + if (use2mutexes) + mutex2->unlock(); + mutex1->unlock(); + + QThread::yieldCurrentThread(); + } + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); + } + } +}; + +void tst_QMutex::contendedQMutex() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); + + QMutex mutex1, mutex2; + + QList threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new QMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); +} + +class QMutexLockerThread : public QThread +{ + QMutex *mutex1, *mutex2; + int iterations, msleepDuration; + bool use2mutexes; +public: + bool done; + QMutexLockerThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) + { } + void run() override + { + forever { + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + { + QMutexLocker locker1(mutex1); + QMutexLocker locker2(use2mutexes ? mutex2 : 0); + if (msleepDuration >= 0) + msleep(msleepDuration); + } + + QThread::yieldCurrentThread(); + } + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); + } + } +}; + +void tst_QMutex::contendedQMutexLocker() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); + + QMutex mutex1, mutex2; + + QList threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new QMutexLockerThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); +} + +QTEST_MAIN(tst_QMutex) + +#include "tst_bench_qmutex.moc" diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp deleted file mode 100644 index 9b14cbca5d..0000000000 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -#include - -//#define USE_SEM_T - -#if defined(Q_OS_UNIX) -#if !defined(USE_SEM_T) -# include -# include -typedef pthread_mutex_t NativeMutexType; -void NativeMutexInitialize(NativeMutexType *mutex) -{ - pthread_mutex_init(mutex, NULL); -} -void NativeMutexDestroy(NativeMutexType *mutex) -{ - pthread_mutex_destroy(mutex); -} -void NativeMutexLock(NativeMutexType *mutex) -{ - pthread_mutex_lock(mutex); -} -void NativeMutexUnlock(NativeMutexType *mutex) -{ - pthread_mutex_unlock(mutex); -} -#else -# include -typedef sem_t NativeMutexType; -void NativeMutexInitialize(NativeMutexType *mutex) -{ - sem_init(mutex, false, 1); -} -void NativeMutexDestroy(NativeMutexType *mutex) -{ - sem_destroy(mutex); -} -void NativeMutexLock(NativeMutexType *mutex) -{ - sem_wait(mutex); -} -void NativeMutexUnlock(NativeMutexType *mutex) -{ - sem_post(mutex); -} -#endif -#elif defined(Q_OS_WIN) -# define _WIN32_WINNT 0x0400 -# include -typedef CRITICAL_SECTION NativeMutexType; -void NativeMutexInitialize(NativeMutexType *mutex) -{ - InitializeCriticalSection(mutex); -} -void NativeMutexDestroy(NativeMutexType *mutex) -{ - DeleteCriticalSection(mutex); -} -void NativeMutexLock(NativeMutexType *mutex) -{ - EnterCriticalSection(mutex); -} -void NativeMutexUnlock(NativeMutexType *mutex) -{ - LeaveCriticalSection(mutex); -} -#endif - -class tst_QMutex : public QObject -{ - Q_OBJECT - - int threadCount; - -public: - // barriers for the contended tests - static QSemaphore semaphore1, semaphore2, semaphore3, semaphore4; - - tst_QMutex() - { - // at least 2 threads, even on single cpu/core machines - threadCount = qMax(2, QThread::idealThreadCount()); - qDebug("thread count: %d", threadCount); - } - -private slots: - void noThread_data(); - void noThread(); - - void constructionNative(); - void uncontendedNative(); - void constructionQMutex(); - void uncontendedQMutex(); - void uncontendedQMutexLocker(); - - void contendedNative_data(); - void contendedQMutex_data() { contendedNative_data(); } - void contendedQMutexLocker_data() { contendedNative_data(); } - - void contendedNative(); - void contendedQMutex(); - void contendedQMutexLocker(); -}; - -QSemaphore tst_QMutex::semaphore1; -QSemaphore tst_QMutex::semaphore2; -QSemaphore tst_QMutex::semaphore3; -QSemaphore tst_QMutex::semaphore4; - -void tst_QMutex::noThread_data() -{ - QTest::addColumn("t"); - - QTest::newRow("noLock") << 1; - QTest::newRow("QMutex") << 3; - QTest::newRow("QMutexLocker") << 4; -} - -void tst_QMutex::noThread() -{ - volatile int count = 0; - const int N = 5000000; - QMutex mtx; - - QFETCH(int, t); - switch(t) { - case 1: - QBENCHMARK { - count = 0; - for (int i = 0; i < N; i++) { - QtPrivate::volatilePreIncrement(count); - } - } - break; - case 3: - QBENCHMARK { - count = 0; - for (int i = 0; i < N; i++) { - mtx.lock(); - QtPrivate::volatilePreIncrement(count); - mtx.unlock(); - } - } - break; - case 4: - QBENCHMARK { - count = 0; - for (int i = 0; i < N; i++) { - QMutexLocker locker(&mtx); - QtPrivate::volatilePreIncrement(count); - } - } - break; - } - QCOMPARE(int(count), N); -} - -void tst_QMutex::constructionNative() -{ - QBENCHMARK { - NativeMutexType mutex; - NativeMutexInitialize(&mutex); - NativeMutexDestroy(&mutex); - } -} - -void tst_QMutex::uncontendedNative() -{ - NativeMutexType mutex; - NativeMutexInitialize(&mutex); - QBENCHMARK { - NativeMutexLock(&mutex); - NativeMutexUnlock(&mutex); - } - NativeMutexDestroy(&mutex); -} - -void tst_QMutex::constructionQMutex() -{ - QBENCHMARK { - QMutex mutex; - Q_UNUSED(mutex); - } -} - -void tst_QMutex::uncontendedQMutex() -{ - QMutex mutex; - QBENCHMARK { - mutex.lock(); - mutex.unlock(); - } -} - -void tst_QMutex::uncontendedQMutexLocker() -{ - QMutex mutex; - QBENCHMARK { - QMutexLocker locker(&mutex); - } -} - -void tst_QMutex::contendedNative_data() -{ - QTest::addColumn("iterations"); - QTest::addColumn("msleepDuration"); - QTest::addColumn("use2mutexes"); - - QTest::newRow("baseline") << 0 << -1 << false; - - QTest::newRow("no msleep, 1 mutex") << 1000 << -1 << false; - QTest::newRow("no msleep, 2 mutexes") << 1000 << -1 << true; - QTest::newRow("msleep(0), 1 mutex") << 1000 << 0 << false; - QTest::newRow("msleep(0), 2 mutexes") << 1000 << 0 << true; - QTest::newRow("msleep(1), 1 mutex") << 10 << 1 << false; - QTest::newRow("msleep(1), 2 mutexes") << 10 << 1 << true; - QTest::newRow("msleep(2), 1 mutex") << 10 << 2 << false; - QTest::newRow("msleep(2), 2 mutexes") << 10 << 2 << true; - QTest::newRow("msleep(10), 1 mutex") << 10 << 10 << false; - QTest::newRow("msleep(10), 2 mutexes") << 10 << 10 << true; -} - -class NativeMutexThread : public QThread -{ - NativeMutexType *mutex1, *mutex2; - int iterations, msleepDuration; - bool use2mutexes; -public: - bool done; - NativeMutexThread(NativeMutexType *mutex1, NativeMutexType *mutex2, int iterations, int msleepDuration, bool use2mutexes) - : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) - { } - void run() override - { - forever { - tst_QMutex::semaphore1.release(); - tst_QMutex::semaphore2.acquire(); - if (done) - break; - for (int i = 0; i < iterations; ++i) { - NativeMutexLock(mutex1); - if (use2mutexes) - NativeMutexLock(mutex2); - if (msleepDuration >= 0) - msleep(msleepDuration); - if (use2mutexes) - NativeMutexUnlock(mutex2); - NativeMutexUnlock(mutex1); - - QThread::yieldCurrentThread(); - } - tst_QMutex::semaphore3.release(); - tst_QMutex::semaphore4.acquire(); - } - } -}; - -void tst_QMutex::contendedNative() -{ - QFETCH(int, iterations); - QFETCH(int, msleepDuration); - QFETCH(bool, use2mutexes); - - NativeMutexType mutex1, mutex2; - NativeMutexInitialize(&mutex1); - NativeMutexInitialize(&mutex2); - - QList threads(threadCount); - for (int i = 0; i < threads.count(); ++i) { - threads[i] = new NativeMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); - threads[i]->start(); - } - - QBENCHMARK { - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - semaphore3.acquire(threadCount); - semaphore4.release(threadCount); - } - - for (int i = 0; i < threads.count(); ++i) - threads[i]->done = true; - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - for (int i = 0; i < threads.count(); ++i) - threads[i]->wait(); - qDeleteAll(threads); - - NativeMutexDestroy(&mutex1); - NativeMutexDestroy(&mutex2); -} - -class QMutexThread : public QThread -{ - QMutex *mutex1, *mutex2; - int iterations, msleepDuration; - bool use2mutexes; -public: - bool done; - QMutexThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) - : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) - { } - void run() override - { - forever { - tst_QMutex::semaphore1.release(); - tst_QMutex::semaphore2.acquire(); - if (done) - break; - for (int i = 0; i < iterations; ++i) { - mutex1->lock(); - if (use2mutexes) - mutex2->lock(); - if (msleepDuration >= 0) - msleep(msleepDuration); - if (use2mutexes) - mutex2->unlock(); - mutex1->unlock(); - - QThread::yieldCurrentThread(); - } - tst_QMutex::semaphore3.release(); - tst_QMutex::semaphore4.acquire(); - } - } -}; - -void tst_QMutex::contendedQMutex() -{ - QFETCH(int, iterations); - QFETCH(int, msleepDuration); - QFETCH(bool, use2mutexes); - - QMutex mutex1, mutex2; - - QList threads(threadCount); - for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); - threads[i]->start(); - } - - QBENCHMARK { - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - semaphore3.acquire(threadCount); - semaphore4.release(threadCount); - } - - for (int i = 0; i < threads.count(); ++i) - threads[i]->done = true; - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - for (int i = 0; i < threads.count(); ++i) - threads[i]->wait(); - qDeleteAll(threads); -} - -class QMutexLockerThread : public QThread -{ - QMutex *mutex1, *mutex2; - int iterations, msleepDuration; - bool use2mutexes; -public: - bool done; - QMutexLockerThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) - : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) - { } - void run() override - { - forever { - tst_QMutex::semaphore1.release(); - tst_QMutex::semaphore2.acquire(); - if (done) - break; - for (int i = 0; i < iterations; ++i) { - { - QMutexLocker locker1(mutex1); - QMutexLocker locker2(use2mutexes ? mutex2 : 0); - if (msleepDuration >= 0) - msleep(msleepDuration); - } - - QThread::yieldCurrentThread(); - } - tst_QMutex::semaphore3.release(); - tst_QMutex::semaphore4.acquire(); - } - } -}; - -void tst_QMutex::contendedQMutexLocker() -{ - QFETCH(int, iterations); - QFETCH(int, msleepDuration); - QFETCH(bool, use2mutexes); - - QMutex mutex1, mutex2; - - QList threads(threadCount); - for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexLockerThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); - threads[i]->start(); - } - - QBENCHMARK { - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - semaphore3.acquire(threadCount); - semaphore4.release(threadCount); - } - - for (int i = 0; i < threads.count(); ++i) - threads[i]->done = true; - semaphore1.acquire(threadCount); - semaphore2.release(threadCount); - for (int i = 0; i < threads.count(); ++i) - threads[i]->wait(); - qDeleteAll(threads); -} - -QTEST_MAIN(tst_QMutex) -#include "tst_qmutex.moc" diff --git a/tests/benchmarks/corelib/thread/qreadwritelock/CMakeLists.txt b/tests/benchmarks/corelib/thread/qreadwritelock/CMakeLists.txt index 79d3a2f879..901f9609bc 100644 --- a/tests/benchmarks/corelib/thread/qreadwritelock/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qreadwritelock/CMakeLists.txt @@ -1,16 +1,11 @@ -# Generated from qreadwritelock.pro. - ##################################################################### ## tst_bench_qreadwritelock Binary: ##################################################################### qt_internal_add_benchmark(tst_bench_qreadwritelock SOURCES - tst_qreadwritelock.cpp + tst_bench_qreadwritelock.cpp PUBLIC_LIBRARIES Qt::CorePrivate Qt::Test ) - -#### Keys ignored in scope 1:.:.:qreadwritelock.pro:: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/thread/qreadwritelock/tst_bench_qreadwritelock.cpp b/tests/benchmarks/corelib/thread/qreadwritelock/tst_bench_qreadwritelock.cpp new file mode 100644 index 0000000000..f0ec45e267 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qreadwritelock/tst_bench_qreadwritelock.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Olivier Goffart +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#if __has_include() +#if __cplusplus > 201103L +#include +#endif +#endif +#include + +// Wrapers that take pointers instead of reference to have the same interface as Qt +template +struct LockerWrapper : T +{ + LockerWrapper(typename T::mutex_type *mtx) + : T(*mtx) + { + } +}; + +int threadCount; + +class tst_QReadWriteLock : public QObject +{ + Q_OBJECT +public: + tst_QReadWriteLock() + { + // at least 2 threads, even on single cpu/core machines + threadCount = qMax(2, QThread::idealThreadCount()); + qDebug("thread count: %d", threadCount); + } + +private slots: + void uncontended_data(); + void uncontended(); + void readOnly_data(); + void readOnly(); + void writeOnly_data(); + void writeOnly(); + // void readWrite(); +}; + +struct FunctionPtrHolder +{ + FunctionPtrHolder(QFunctionPointer value = nullptr) + : value(value) + { + } + QFunctionPointer value; +}; +Q_DECLARE_METATYPE(FunctionPtrHolder) + +struct FakeLock +{ + FakeLock(volatile int *i) { *i = 0; } +}; + +enum { Iterations = 1000000 }; + +template +void testUncontended() +{ + Mutex lock; + QBENCHMARK { + for (int i = 0; i < Iterations; ++i) { + Locker locker(&lock); + } + } +} + +void tst_QReadWriteLock::uncontended_data() +{ + QTest::addColumn("holder"); + + QTest::newRow("nothing") << FunctionPtrHolder(testUncontended); + QTest::newRow("QMutex") << FunctionPtrHolder(testUncontended>); + QTest::newRow("QReadWriteLock, read") + << FunctionPtrHolder(testUncontended); + QTest::newRow("QReadWriteLock, write") + << FunctionPtrHolder(testUncontended); + QTest::newRow("std::mutex") << FunctionPtrHolder( + testUncontended>>); +#ifdef __cpp_lib_shared_mutex + QTest::newRow("std::shared_mutex, read") << FunctionPtrHolder( + testUncontended>>); + QTest::newRow("std::shared_mutex, write") << FunctionPtrHolder( + testUncontended>>); +#endif +#if defined __cpp_lib_shared_timed_mutex + QTest::newRow("std::shared_timed_mutex, read") << FunctionPtrHolder( + testUncontended>>); + QTest::newRow("std::shared_timed_mutex, write") << FunctionPtrHolder( + testUncontended>>); +#endif +} + +void tst_QReadWriteLock::uncontended() +{ + QFETCH(FunctionPtrHolder, holder); + holder.value(); +} + +static QHash global_hash; + +template +void testReadOnly() +{ + struct Thread : QThread + { + Mutex *lock; + void run() override + { + for (int i = 0; i < Iterations; ++i) { + QString s = QString::number(i); // Do something outside the lock + Locker locker(lock); + global_hash.contains(s); + } + } + }; + Mutex lock; + std::vector> threads; + for (int i = 0; i < threadCount; ++i) { + auto t = std::make_unique(); + t->lock = &lock; + threads.push_back(std::move(t)); + } + QBENCHMARK { + for (auto &t : threads) { + t->start(); + } + for (auto &t : threads) { + t->wait(); + } + } +} + +void tst_QReadWriteLock::readOnly_data() +{ + QTest::addColumn("holder"); + + QTest::newRow("nothing") << FunctionPtrHolder(testReadOnly); + QTest::newRow("QMutex") << FunctionPtrHolder(testReadOnly>); + QTest::newRow("QReadWriteLock") << FunctionPtrHolder(testReadOnly); + QTest::newRow("std::mutex") << FunctionPtrHolder( + testReadOnly>>); +#ifdef __cpp_lib_shared_mutex + QTest::newRow("std::shared_mutex") << FunctionPtrHolder( + testReadOnly>>); +#endif +#if defined __cpp_lib_shared_timed_mutex + QTest::newRow("std::shared_timed_mutex") << FunctionPtrHolder( + testReadOnly>>); +#endif +} + +void tst_QReadWriteLock::readOnly() +{ + QFETCH(FunctionPtrHolder, holder); + holder.value(); +} + +static QString global_string; + +template +void testWriteOnly() +{ + struct Thread : QThread + { + Mutex *lock; + void run() override + { + for (int i = 0; i < Iterations; ++i) { + QString s = QString::number(i); // Do something outside the lock + Locker locker(lock); + global_string = s; + } + } + }; + Mutex lock; + std::vector> threads; + for (int i = 0; i < threadCount; ++i) { + auto t = std::make_unique(); + t->lock = &lock; + threads.push_back(std::move(t)); + } + QBENCHMARK { + for (auto &t : threads) { + t->start(); + } + for (auto &t : threads) { + t->wait(); + } + } +} + +void tst_QReadWriteLock::writeOnly_data() +{ + QTest::addColumn("holder"); + + // QTest::newRow("nothing") << FunctionPtrHolder(testWriteOnly); + QTest::newRow("QMutex") << FunctionPtrHolder(testWriteOnly>); + QTest::newRow("QReadWriteLock") << FunctionPtrHolder(testWriteOnly); + QTest::newRow("std::mutex") << FunctionPtrHolder( + testWriteOnly>>); +#ifdef __cpp_lib_shared_mutex + QTest::newRow("std::shared_mutex") << FunctionPtrHolder( + testWriteOnly>>); +#endif +#if defined __cpp_lib_shared_timed_mutex + QTest::newRow("std::shared_timed_mutex") << FunctionPtrHolder( + testWriteOnly>>); +#endif +} + +void tst_QReadWriteLock::writeOnly() +{ + QFETCH(FunctionPtrHolder, holder); + holder.value(); +} + +QTEST_MAIN(tst_QReadWriteLock) +#include "tst_bench_qreadwritelock.moc" diff --git a/tests/benchmarks/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp b/tests/benchmarks/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp deleted file mode 100644 index 1018dae878..0000000000 --- a/tests/benchmarks/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Olivier Goffart -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#if __has_include() -#if __cplusplus > 201103L -#include -#endif -#endif -#include - -// Wrapers that take pointers instead of reference to have the same interface as Qt -template -struct LockerWrapper : T -{ - LockerWrapper(typename T::mutex_type *mtx) - : T(*mtx) - { - } -}; - -int threadCount; - -class tst_QReadWriteLock : public QObject -{ - Q_OBJECT -public: - tst_QReadWriteLock() - { - // at least 2 threads, even on single cpu/core machines - threadCount = qMax(2, QThread::idealThreadCount()); - qDebug("thread count: %d", threadCount); - } - -private slots: - void uncontended_data(); - void uncontended(); - void readOnly_data(); - void readOnly(); - void writeOnly_data(); - void writeOnly(); - // void readWrite(); -}; - -struct FunctionPtrHolder -{ - FunctionPtrHolder(QFunctionPointer value = nullptr) - : value(value) - { - } - QFunctionPointer value; -}; -Q_DECLARE_METATYPE(FunctionPtrHolder) - -struct FakeLock -{ - FakeLock(volatile int *i) { *i = 0; } -}; - -enum { Iterations = 1000000 }; - -template -void testUncontended() -{ - Mutex lock; - QBENCHMARK { - for (int i = 0; i < Iterations; ++i) { - Locker locker(&lock); - } - } -} - -void tst_QReadWriteLock::uncontended_data() -{ - QTest::addColumn("holder"); - - QTest::newRow("nothing") << FunctionPtrHolder(testUncontended); - QTest::newRow("QMutex") << FunctionPtrHolder(testUncontended>); - QTest::newRow("QReadWriteLock, read") - << FunctionPtrHolder(testUncontended); - QTest::newRow("QReadWriteLock, write") - << FunctionPtrHolder(testUncontended); - QTest::newRow("std::mutex") << FunctionPtrHolder( - testUncontended>>); -#ifdef __cpp_lib_shared_mutex - QTest::newRow("std::shared_mutex, read") << FunctionPtrHolder( - testUncontended>>); - QTest::newRow("std::shared_mutex, write") << FunctionPtrHolder( - testUncontended>>); -#endif -#if defined __cpp_lib_shared_timed_mutex - QTest::newRow("std::shared_timed_mutex, read") << FunctionPtrHolder( - testUncontended>>); - QTest::newRow("std::shared_timed_mutex, write") << FunctionPtrHolder( - testUncontended>>); -#endif -} - -void tst_QReadWriteLock::uncontended() -{ - QFETCH(FunctionPtrHolder, holder); - holder.value(); -} - -static QHash global_hash; - -template -void testReadOnly() -{ - struct Thread : QThread - { - Mutex *lock; - void run() override - { - for (int i = 0; i < Iterations; ++i) { - QString s = QString::number(i); // Do something outside the lock - Locker locker(lock); - global_hash.contains(s); - } - } - }; - Mutex lock; - std::vector> threads; - for (int i = 0; i < threadCount; ++i) { - auto t = std::make_unique(); - t->lock = &lock; - threads.push_back(std::move(t)); - } - QBENCHMARK { - for (auto &t : threads) { - t->start(); - } - for (auto &t : threads) { - t->wait(); - } - } -} - -void tst_QReadWriteLock::readOnly_data() -{ - QTest::addColumn("holder"); - - QTest::newRow("nothing") << FunctionPtrHolder(testReadOnly); - QTest::newRow("QMutex") << FunctionPtrHolder(testReadOnly>); - QTest::newRow("QReadWriteLock") << FunctionPtrHolder(testReadOnly); - QTest::newRow("std::mutex") << FunctionPtrHolder( - testReadOnly>>); -#ifdef __cpp_lib_shared_mutex - QTest::newRow("std::shared_mutex") << FunctionPtrHolder( - testReadOnly>>); -#endif -#if defined __cpp_lib_shared_timed_mutex - QTest::newRow("std::shared_timed_mutex") << FunctionPtrHolder( - testReadOnly>>); -#endif -} - -void tst_QReadWriteLock::readOnly() -{ - QFETCH(FunctionPtrHolder, holder); - holder.value(); -} - -static QString global_string; - -template -void testWriteOnly() -{ - struct Thread : QThread - { - Mutex *lock; - void run() override - { - for (int i = 0; i < Iterations; ++i) { - QString s = QString::number(i); // Do something outside the lock - Locker locker(lock); - global_string = s; - } - } - }; - Mutex lock; - std::vector> threads; - for (int i = 0; i < threadCount; ++i) { - auto t = std::make_unique(); - t->lock = &lock; - threads.push_back(std::move(t)); - } - QBENCHMARK { - for (auto &t : threads) { - t->start(); - } - for (auto &t : threads) { - t->wait(); - } - } -} - -void tst_QReadWriteLock::writeOnly_data() -{ - QTest::addColumn("holder"); - - // QTest::newRow("nothing") << FunctionPtrHolder(testWriteOnly); - QTest::newRow("QMutex") << FunctionPtrHolder(testWriteOnly>); - QTest::newRow("QReadWriteLock") << FunctionPtrHolder(testWriteOnly); - QTest::newRow("std::mutex") << FunctionPtrHolder( - testWriteOnly>>); -#ifdef __cpp_lib_shared_mutex - QTest::newRow("std::shared_mutex") << FunctionPtrHolder( - testWriteOnly>>); -#endif -#if defined __cpp_lib_shared_timed_mutex - QTest::newRow("std::shared_timed_mutex") << FunctionPtrHolder( - testWriteOnly>>); -#endif -} - -void tst_QReadWriteLock::writeOnly() -{ - QFETCH(FunctionPtrHolder, holder); - holder.value(); -} - -QTEST_MAIN(tst_QReadWriteLock) -#include "tst_qreadwritelock.moc" diff --git a/tests/benchmarks/corelib/thread/qthreadpool/CMakeLists.txt b/tests/benchmarks/corelib/thread/qthreadpool/CMakeLists.txt index 7b0c81891e..0d1f145e25 100644 --- a/tests/benchmarks/corelib/thread/qthreadpool/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qthreadpool/CMakeLists.txt @@ -1,15 +1,10 @@ -# Generated from qthreadpool.pro. - ##################################################################### ## tst_bench_qthreadpool Binary: ##################################################################### qt_internal_add_benchmark(tst_bench_qthreadpool SOURCES - tst_qthreadpool.cpp + tst_bench_qthreadpool.cpp PUBLIC_LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:qthreadpool.pro:: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/thread/qthreadpool/tst_bench_qthreadpool.cpp b/tests/benchmarks/corelib/thread/qthreadpool/tst_bench_qthreadpool.cpp new file mode 100644 index 0000000000..a64dbd15c9 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadpool/tst_bench_qthreadpool.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2013 David Faure +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class tst_QThreadPool : public QObject +{ + Q_OBJECT + +public: + tst_QThreadPool(); + ~tst_QThreadPool(); + +private slots: + void startRunnables(); + void activeThreadCount(); +}; + +tst_QThreadPool::tst_QThreadPool() +{ +} + +tst_QThreadPool::~tst_QThreadPool() +{ +} + +class NoOpRunnable : public QRunnable +{ +public: + void run() override { + } +}; + +void tst_QThreadPool::startRunnables() +{ + QThreadPool threadPool; + threadPool.setMaxThreadCount(10); + QBENCHMARK { + threadPool.start(new NoOpRunnable()); + } +} + +void tst_QThreadPool::activeThreadCount() +{ + QThreadPool threadPool; + threadPool.start(new NoOpRunnable()); + QBENCHMARK { + QVERIFY(threadPool.activeThreadCount() <= 10); + } +} + +QTEST_MAIN(tst_QThreadPool) + +#include "tst_bench_qthreadpool.moc" diff --git a/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp deleted file mode 100644 index 10928e3afc..0000000000 --- a/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 David Faure -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -class tst_QThreadPool : public QObject -{ - Q_OBJECT - -public: - tst_QThreadPool(); - ~tst_QThreadPool(); - -private slots: - void startRunnables(); - void activeThreadCount(); -}; - -tst_QThreadPool::tst_QThreadPool() -{ -} - -tst_QThreadPool::~tst_QThreadPool() -{ -} - -class NoOpRunnable : public QRunnable -{ -public: - void run() override { - } -}; - -void tst_QThreadPool::startRunnables() -{ - QThreadPool threadPool; - threadPool.setMaxThreadCount(10); - QBENCHMARK { - threadPool.start(new NoOpRunnable()); - } -} - -void tst_QThreadPool::activeThreadCount() -{ - QThreadPool threadPool; - threadPool.start(new NoOpRunnable()); - QBENCHMARK { - QVERIFY(threadPool.activeThreadCount() <= 10); - } -} - -QTEST_MAIN(tst_QThreadPool) -#include "tst_qthreadpool.moc" diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/CMakeLists.txt b/tests/benchmarks/corelib/thread/qthreadstorage/CMakeLists.txt index 78ac072d35..7f5de4e9ab 100644 --- a/tests/benchmarks/corelib/thread/qthreadstorage/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qthreadstorage/CMakeLists.txt @@ -1,15 +1,10 @@ -# Generated from qthreadstorage.pro. - ##################################################################### ## tst_bench_qthreadstorage Binary: ##################################################################### qt_internal_add_benchmark(tst_bench_qthreadstorage SOURCES - tst_qthreadstorage.cpp + tst_bench_qthreadstorage.cpp PUBLIC_LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:qthreadstorage.pro:: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/tst_bench_qthreadstorage.cpp b/tests/benchmarks/corelib/thread/qthreadstorage/tst_bench_qthreadstorage.cpp new file mode 100644 index 0000000000..6230cd3187 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadstorage/tst_bench_qthreadstorage.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +QThreadStorage dummy[8]; + +QThreadStorage tls1; + +class tst_QThreadStorage : public QObject +{ + Q_OBJECT + +public: + tst_QThreadStorage(); + virtual ~tst_QThreadStorage(); + +public slots: + void init(); + void cleanup(); + +private slots: + void construct(); + void get(); + void set(); +}; + +tst_QThreadStorage::tst_QThreadStorage() +{ +} + +tst_QThreadStorage::~tst_QThreadStorage() +{ +} + +void tst_QThreadStorage::init() +{ + dummy[1].setLocalData(new int(5)); + dummy[2].setLocalData(new int(4)); + dummy[3].setLocalData(new int(3)); + tls1.setLocalData(new QString()); +} + +void tst_QThreadStorage::cleanup() +{ +} + +void tst_QThreadStorage::construct() +{ + QBENCHMARK { + QThreadStorage ts; + } +} + + +void tst_QThreadStorage::get() +{ + QThreadStorage ts; + ts.setLocalData(new int(45)); + + int count = 0; + QBENCHMARK { + int *i = ts.localData(); + count += *i; + } + ts.setLocalData(0); +} + +void tst_QThreadStorage::set() +{ + QThreadStorage ts; + + int count = 0; + QBENCHMARK { + ts.setLocalData(new int(count)); + count++; + } + ts.setLocalData(0); +} + +QTEST_MAIN(tst_QThreadStorage) + +#include "tst_bench_qthreadstorage.moc" diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp deleted file mode 100644 index c8f9f23c76..0000000000 --- a/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QThreadStorage dummy[8]; - -QThreadStorage tls1; - -class tst_QThreadStorage : public QObject -{ - Q_OBJECT - -public: - tst_QThreadStorage(); - virtual ~tst_QThreadStorage(); - -public slots: - void init(); - void cleanup(); - -private slots: - void construct(); - void get(); - void set(); -}; - -tst_QThreadStorage::tst_QThreadStorage() -{ -} - -tst_QThreadStorage::~tst_QThreadStorage() -{ -} - -void tst_QThreadStorage::init() -{ - dummy[1].setLocalData(new int(5)); - dummy[2].setLocalData(new int(4)); - dummy[3].setLocalData(new int(3)); - tls1.setLocalData(new QString()); -} - -void tst_QThreadStorage::cleanup() -{ -} - -void tst_QThreadStorage::construct() -{ - QBENCHMARK { - QThreadStorage ts; - } -} - - -void tst_QThreadStorage::get() -{ - QThreadStorage ts; - ts.setLocalData(new int(45)); - - int count = 0; - QBENCHMARK { - int *i = ts.localData(); - count += *i; - } - ts.setLocalData(0); -} - -void tst_QThreadStorage::set() -{ - QThreadStorage ts; - - int count = 0; - QBENCHMARK { - ts.setLocalData(new int(count)); - count++; - } - ts.setLocalData(0); -} - - -QTEST_MAIN(tst_QThreadStorage) -#include "tst_qthreadstorage.moc" diff --git a/tests/benchmarks/corelib/thread/qwaitcondition/CMakeLists.txt b/tests/benchmarks/corelib/thread/qwaitcondition/CMakeLists.txt index 68c6e88342..13814d7074 100644 --- a/tests/benchmarks/corelib/thread/qwaitcondition/CMakeLists.txt +++ b/tests/benchmarks/corelib/thread/qwaitcondition/CMakeLists.txt @@ -1,15 +1,10 @@ -# Generated from qwaitcondition.pro. - ##################################################################### ## tst_bench_qwaitcondition Binary: ##################################################################### qt_internal_add_benchmark(tst_bench_qwaitcondition SOURCES - tst_qwaitcondition.cpp + tst_bench_qwaitcondition.cpp PUBLIC_LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:qwaitcondition.pro:: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp b/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp new file mode 100644 index 0000000000..19d3964c7a --- /dev/null +++ b/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include + + +class tst_QWaitCondition : public QObject +{ + Q_OBJECT + +public: + tst_QWaitCondition() + { + } + +private slots: + void oscillate_mutex_data(); + void oscillate_mutex(); + void oscillate_writelock_data(); + void oscillate_writelock(); +}; + + +int turn; +const int threadCount = 10; +QWaitCondition cond; + +template +class OscillateThread : public QThread +{ +public: + Mutex *mutex; + int m_threadid; + int timeout; + + void run() override + { + for (int count = 0; count < 5000; ++count) { + + Locker lock(mutex); + while (m_threadid != turn) { + cond.wait(mutex, timeout); + } + turn = (turn+1) % threadCount; + cond.wakeAll(); + } + } +}; + +template +void oscillate(unsigned long timeout) { + + OscillateThread thrd[threadCount]; + Mutex m; + for (int i = 0; i < threadCount; ++i) { + thrd[i].mutex = &m; + thrd[i].m_threadid = i; + thrd[i].timeout = timeout; + } + + QBENCHMARK { + for (int i = 0; i < threadCount; ++i) { + thrd[i].start(); + } + for (int i = 0; i < threadCount; ++i) { + thrd[i].wait(); + } + } + +} + +void tst_QWaitCondition::oscillate_mutex_data() +{ + QTest::addColumn("timeout"); + + QTest::newRow("0") << 0ul; + QTest::newRow("1") << 1ul; + QTest::newRow("1000") << 1000ul; + QTest::newRow("forever") << ULONG_MAX; +} + +void tst_QWaitCondition::oscillate_mutex() +{ + QFETCH(unsigned long, timeout); + oscillate>(timeout); +} + +void tst_QWaitCondition::oscillate_writelock_data() +{ + oscillate_mutex_data(); +} + +void tst_QWaitCondition::oscillate_writelock() +{ + QFETCH(unsigned long, timeout); + oscillate(timeout); +} + +QTEST_MAIN(tst_QWaitCondition) + +#include "tst_bench_qwaitcondition.moc" diff --git a/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp deleted file mode 100644 index b87da463dc..0000000000 --- a/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - - -class tst_QWaitCondition : public QObject -{ - Q_OBJECT - -public: - tst_QWaitCondition() - { - } - -private slots: - void oscillate_mutex_data(); - void oscillate_mutex(); - void oscillate_writelock_data(); - void oscillate_writelock(); -}; - - -int turn; -const int threadCount = 10; -QWaitCondition cond; - -template -class OscillateThread : public QThread -{ -public: - Mutex *mutex; - int m_threadid; - int timeout; - - void run() override - { - for (int count = 0; count < 5000; ++count) { - - Locker lock(mutex); - while (m_threadid != turn) { - cond.wait(mutex, timeout); - } - turn = (turn+1) % threadCount; - cond.wakeAll(); - } - } -}; - -template -void oscillate(unsigned long timeout) { - - OscillateThread thrd[threadCount]; - Mutex m; - for (int i = 0; i < threadCount; ++i) { - thrd[i].mutex = &m; - thrd[i].m_threadid = i; - thrd[i].timeout = timeout; - } - - QBENCHMARK { - for (int i = 0; i < threadCount; ++i) { - thrd[i].start(); - } - for (int i = 0; i < threadCount; ++i) { - thrd[i].wait(); - } - } - -} - -void tst_QWaitCondition::oscillate_mutex_data() -{ - QTest::addColumn("timeout"); - - QTest::newRow("0") << 0ul; - QTest::newRow("1") << 1ul; - QTest::newRow("1000") << 1000ul; - QTest::newRow("forever") << ULONG_MAX; -} - -void tst_QWaitCondition::oscillate_mutex() -{ - QFETCH(unsigned long, timeout); - oscillate>(timeout); -} - -void tst_QWaitCondition::oscillate_writelock_data() -{ - oscillate_mutex_data(); -} - -void tst_QWaitCondition::oscillate_writelock() -{ - QFETCH(unsigned long, timeout); - oscillate(timeout); -} - - -QTEST_MAIN(tst_QWaitCondition) -#include "tst_qwaitcondition.moc" -- cgit v1.2.3