diff --git a/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp b/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp index 19d3964c7a6..3612b8784bd 100644 --- a/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp +++ b/tests/benchmarks/corelib/thread/qwaitcondition/tst_bench_qwaitcondition.cpp @@ -30,7 +30,12 @@ #include #include +#include +#include +#include + +using namespace std::chrono_literals; class tst_QWaitCondition : public QObject { @@ -42,24 +47,67 @@ public: } private slots: + void oscillate_QWaitCondition_QMutex_data() { oscillate_mutex_data(); } + void oscillate_QWaitCondition_QMutex(); + void oscillate_QWaitCondition_QReadWriteLock_data() { oscillate_mutex_data(); } + void oscillate_QWaitCondition_QReadWriteLock(); + void oscillate_std_condition_variable_std_mutex_data() { oscillate_mutex_data(); } + void oscillate_std_condition_variable_std_mutex(); + void oscillate_std_condition_variable_any_QMutex_data() { oscillate_mutex_data(); } + void oscillate_std_condition_variable_any_QMutex(); + void oscillate_std_condition_variable_any_QReadWriteLock_data() { oscillate_mutex_data(); } + void oscillate_std_condition_variable_any_QReadWriteLock(); + +private: void oscillate_mutex_data(); - void oscillate_mutex(); - void oscillate_writelock_data(); - void oscillate_writelock(); }; int turn; const int threadCount = 10; QWaitCondition cond; +std::condition_variable cv; +std::condition_variable_any cva; -template +template +Cond *get(); + +template <> std::condition_variable *get() { return &cv; } +template <> std::condition_variable_any *get() { return &cva; } + +template class OscillateThread : public QThread { public: Mutex *mutex; int m_threadid; - int timeout; + unsigned long timeout; + + void run() override + { + for (int count = 0; count < 5000; ++count) { + Locker lock(*mutex); + while (m_threadid != turn) { + if (timeout == ULONG_MAX) + get()->wait(lock); + else if (timeout == 0) // Windows doesn't unlock the mutex with a zero timeout + get()->wait_for(lock, 1ns); + else + get()->wait_for(lock, timeout * 1ms); + } + turn = (turn+1) % threadCount; + get()->notify_all(); + } + } +}; + +template +class OscillateThread : public QThread +{ +public: + Mutex *mutex; + int m_threadid; + unsigned long timeout; void run() override { @@ -75,10 +123,10 @@ public: } }; -template +template void oscillate(unsigned long timeout) { - OscillateThread thrd[threadCount]; + OscillateThread thrd[threadCount]; Mutex m; for (int i = 0; i < threadCount; ++i) { thrd[i].mutex = &m; @@ -107,21 +155,43 @@ void tst_QWaitCondition::oscillate_mutex_data() QTest::newRow("forever") << ULONG_MAX; } -void tst_QWaitCondition::oscillate_mutex() +void tst_QWaitCondition::oscillate_QWaitCondition_QMutex() { QFETCH(unsigned long, timeout); - oscillate>(timeout); + oscillate>(timeout); } -void tst_QWaitCondition::oscillate_writelock_data() -{ - oscillate_mutex_data(); -} - -void tst_QWaitCondition::oscillate_writelock() +void tst_QWaitCondition::oscillate_QWaitCondition_QReadWriteLock() { QFETCH(unsigned long, timeout); - oscillate(timeout); + oscillate(timeout); +} + +void tst_QWaitCondition::oscillate_std_condition_variable_std_mutex() +{ + QFETCH(unsigned long, timeout); + oscillate>(timeout); +} + + +void tst_QWaitCondition::oscillate_std_condition_variable_any_QMutex() +{ + QFETCH(unsigned long, timeout); + oscillate>(timeout); +} + + +void tst_QWaitCondition::oscillate_std_condition_variable_any_QReadWriteLock() +{ + QFETCH(unsigned long, timeout); + + struct WriteLocker : QWriteLocker { + // adapt to BasicLockable + explicit WriteLocker(QReadWriteLock &m) : QWriteLocker{&m} {} + void lock() { relock(); } + }; + + oscillate(timeout); } QTEST_MAIN(tst_QWaitCondition)