QReadWriteLock: add a check for writeOnly, too

Results on my machine:

  PASS   : tst_QReadWriteLock::writeOnly(QMutex)
  RESULT : tst_QReadWriteLock::writeOnly():QMutex:
     3,607 msecs per iteration (total: 3,607, iterations: 1)
  PASS   : tst_QReadWriteLock::writeOnly(QReadWriteLock)
  RESULT : tst_QReadWriteLock::writeOnly():QReadWriteLock:
     39,703 msecs per iteration (total: 39,703, iterations: 1)
  PASS   : tst_QReadWriteLock::writeOnly(std::mutex)
  RESULT : tst_QReadWriteLock::writeOnly():std::mutex:
     3,697 msecs per iteration (total: 3,697, iterations: 1)
  PASS   : tst_QReadWriteLock::writeOnly(std::shared_mutex)
  RESULT : tst_QReadWriteLock::writeOnly():std::shared_mutex:
     5,727 msecs per iteration (total: 5,727, iterations: 1)
  PASS   : tst_QReadWriteLock::writeOnly(std::shared_timed_mutex)
  RESULT : tst_QReadWriteLock::writeOnly():std::shared_timed_mutex:
     5,921 msecs per iteration (total: 5,921, iterations: 1)

(the 'nothing' test of course doesn't work with writing, as writing to
the same QString from different threads is UB)

Change-Id: Ia78b54963a51eaf6563ce0d243316a3337056a83
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Marc Mutz 2019-09-11 10:39:14 +02:00
parent 0f219d2054
commit 333b1e9229

View File

@ -65,6 +65,8 @@ private slots:
void uncontended();
void readOnly_data();
void readOnly();
void writeOnly_data();
void writeOnly();
// void readWrite();
};
@ -193,5 +195,66 @@ void tst_QReadWriteLock::readOnly()
holder.value();
}
static QString global_string;
template <typename Mutex, typename Locker>
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<std::unique_ptr<Thread>> threads;
for (int i = 0; i < threadCount; ++i) {
auto t = qt_make_unique<Thread>();
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<FunctionPtrHolder>("holder");
// QTest::newRow("nothing") << FunctionPtrHolder(testWriteOnly<int, FakeLock>);
QTest::newRow("QMutex") << FunctionPtrHolder(testWriteOnly<QMutex, QMutexLocker>);
QTest::newRow("QReadWriteLock") << FunctionPtrHolder(testWriteOnly<QReadWriteLock, QWriteLocker>);
QTest::newRow("std::mutex") << FunctionPtrHolder(
testWriteOnly<std::mutex, LockerWrapper<std::unique_lock<std::mutex>>>);
#ifdef __cpp_lib_shared_mutex
QTest::newRow("std::shared_mutex") << FunctionPtrHolder(
testWriteOnly<std::shared_mutex,
LockerWrapper<std::unique_lock<std::shared_mutex>>>);
#endif
#if defined __cpp_lib_shared_timed_mutex
QTest::newRow("std::shared_timed_mutex") << FunctionPtrHolder(
testWriteOnly<std::shared_timed_mutex,
LockerWrapper<std::unique_lock<std::shared_timed_mutex>>>);
#endif
}
void tst_QReadWriteLock::writeOnly()
{
QFETCH(FunctionPtrHolder, holder);
holder.value();
}
QTEST_MAIN(tst_QReadWriteLock)
#include "tst_qreadwritelock.moc"