Benchmark for QWaitCondition

Change-Id: I89fc0819324c12030bc23ba080b21f3d8d5c9852
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Olivier Goffart 2013-10-17 16:01:17 +02:00 committed by The Qt Project
parent 7e468353c3
commit 3d2691ae77
2 changed files with 54 additions and 121 deletions

View File

@ -55,156 +55,88 @@ public:
}
private slots:
void oscillate_data();
void oscillate();
void thrash_data();
void thrash();
public:
static QWaitCondition local, remote;
enum Turn {LocalTurn, RemoteTurn};
static Turn turn;
void oscillate_mutex_data();
void oscillate_mutex();
void oscillate_writelock_data();
void oscillate_writelock();
};
QWaitCondition tst_QWaitCondition::local;
QWaitCondition tst_QWaitCondition::remote;
tst_QWaitCondition::Turn tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
int turn;
const int threadCount = 10;
QWaitCondition cond;
template <class Mutex, class Locker>
class OscillateThread : public QThread
{
public:
bool m_done;
bool m_useMutex;
unsigned long m_timeout;
bool m_wakeOne;
int count;
Mutex *mutex;
int m_threadid;
int timeout;
OscillateThread(bool useMutex, unsigned long timeout, bool wakeOne)
: m_done(false), m_useMutex(useMutex), m_timeout(timeout), m_wakeOne(wakeOne)
{}
void run()
{
QMutex mtx;
QReadWriteLock rwl;
count = 0;
for (int count = 0; count < 5000; ++count) {
forever {
if (m_done)
break;
if (m_useMutex) {
mtx.lock();
while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
tst_QWaitCondition::remote.wait(&mtx, m_timeout);
mtx.unlock();
} else {
rwl.lockForWrite();
while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
tst_QWaitCondition::remote.wait(&rwl, m_timeout);
rwl.unlock();
Locker lock(mutex);
while (m_threadid != turn) {
cond.wait(mutex, timeout);
}
tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
if (m_wakeOne)
tst_QWaitCondition::local.wakeOne();
else
tst_QWaitCondition::local.wakeAll();
count++;
turn = (turn+1) % threadCount;
cond.wakeAll();
}
}
};
void tst_QWaitCondition::oscillate_data()
{
QTest::addColumn<bool>("useMutex");
QTest::addColumn<unsigned long>("timeout");
QTest::addColumn<bool>("wakeOne");
template <class Mutex, class Locker>
void oscillate(unsigned long timeout) {
QTest::newRow("mutex, timeout, one") << true << 1000ul << true;
QTest::newRow("readWriteLock, timeout, one") << false << 1000ul << true;
QTest::newRow("mutex, timeout, all") << true << 1000ul << false;
QTest::newRow("readWriteLock, timeout, all") << false << 1000ul << false;
QTest::newRow("mutex, forever, one") << true << ULONG_MAX << true;
QTest::newRow("readWriteLock, forever, one") << false << ULONG_MAX << true;
QTest::newRow("mutex, forever, all") << true << ULONG_MAX << false;
QTest::newRow("readWriteLock, forever, all") << false << ULONG_MAX << false;
}
void tst_QWaitCondition::oscillate()
{
QMutex mtx;
QReadWriteLock rwl;
QFETCH(bool, useMutex);
QFETCH(unsigned long, timeout);
QFETCH(bool, wakeOne);
turn = LocalTurn;
OscillateThread thrd(useMutex, timeout, wakeOne);
thrd.start();
OscillateThread<Mutex, Locker> 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 {
if (useMutex)
mtx.lock();
else
rwl.lockForWrite();
turn = RemoteTurn;
if (wakeOne)
remote.wakeOne();
else
remote.wakeAll();
if (useMutex) {
while (turn == RemoteTurn)
local.wait(&mtx, timeout);
mtx.unlock();
} else {
while (turn == RemoteTurn)
local.wait(&rwl, timeout);
rwl.unlock();
for (int i = 0; i < threadCount; ++i) {
thrd[i].start();
}
for (int i = 0; i < threadCount; ++i) {
thrd[i].wait();
}
}
thrd.m_done = true;
remote.wakeAll();
thrd.wait();
QCOMPARE(0, 0);
}
void tst_QWaitCondition::thrash_data()
void tst_QWaitCondition::oscillate_mutex_data()
{
oscillate_data();
QTest::addColumn<unsigned long>("timeout");
QTest::newRow("0") << 0ul;
QTest::newRow("1") << 1ul;
QTest::newRow("1000") << 1000ul;
QTest::newRow("forever") << ULONG_MAX;
}
void tst_QWaitCondition::thrash()
void tst_QWaitCondition::oscillate_mutex()
{
QMutex mtx;
mtx.lock();
QFETCH(bool, useMutex);
QFETCH(unsigned long, timeout);
QFETCH(bool, wakeOne);
turn = LocalTurn;
OscillateThread thrd(useMutex, timeout, wakeOne);
thrd.start();
local.wait(&mtx, 1000ul);
mtx.unlock();
QBENCHMARK {
turn = RemoteTurn;
if (wakeOne)
remote.wakeOne();
else
remote.wakeAll();
}
thrd.m_done = true;
turn = RemoteTurn;
remote.wakeAll();
thrd.wait();
QCOMPARE(0, 0);
oscillate<QMutex, QMutexLocker>(timeout);
}
void tst_QWaitCondition::oscillate_writelock_data()
{
oscillate_mutex_data();
}
void tst_QWaitCondition::oscillate_writelock()
{
QFETCH(unsigned long, timeout);
oscillate<QReadWriteLock, QWriteLocker>(timeout);
}
QTEST_MAIN(tst_QWaitCondition)
#include "tst_qwaitcondition.moc"

View File

@ -3,3 +3,4 @@ SUBDIRS = \
qmutex \
qthreadstorage \
qthreadpool \
qwaitcondition \