summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2010-10-12 11:11:38 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2010-12-20 15:38:57 (GMT)
commit9a18739c538013a7f2111e68e9255379cfbd9a57 (patch)
tree37c2db6266e6337d2df9cb59aa3a1ba9e3c72da3 /tests
parent00c4e6d3d4e9196dc1c418c9269fcbed2f49dc87 (diff)
downloadQt-9a18739c538013a7f2111e68e9255379cfbd9a57.zip
Qt-9a18739c538013a7f2111e68e9255379cfbd9a57.tar.gz
Qt-9a18739c538013a7f2111e68e9255379cfbd9a57.tar.bz2
Ensure that every thread does contend in the contention tests
2 semaphore barrier is not enough to ensure that every thread does run as part of the benchmark. It is possible that a single thread, given enough time, could do all the work while the other threads remain dormant. Prevent this by making sure that the each thread rendevous with both the semaphore barriers at the start of their run(), yields after unlocking, and then rendevous again at the end. Reviewed-by: joao
Diffstat (limited to 'tests')
-rw-r--r--tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp93
1 files changed, 60 insertions, 33 deletions
diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
index 7a6b45c..cbfffe5 100644
--- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
+++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
@@ -95,6 +95,9 @@ class tst_QMutex : public QObject
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
@@ -119,6 +122,11 @@ private slots:
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<int>("t");
@@ -220,17 +228,17 @@ void tst_QMutex::contendedNative_data()
class NativeMutexThread : public QThread
{
- QSemaphore *semaphore1, *semaphore2;
NativeMutexType *mutex;
int iterations, msleepDuration;
public:
bool done;
- NativeMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, NativeMutexType *mutex, int iterations, int msleepDuration)
- : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
+ NativeMutexThread(NativeMutexType *mutex, int iterations, int msleepDuration)
+ : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
{ }
void run() {
forever {
- semaphore1->acquire();
+ tst_QMutex::semaphore1.release();
+ tst_QMutex::semaphore2.acquire();
if (done)
break;
for (int i = 0; i < iterations; ++i) {
@@ -238,8 +246,11 @@ public:
if (msleepDuration >= 0)
msleep(msleepDuration);
NativeMutexUnlock(mutex);
+
+ QThread::yieldCurrentThread();
}
- semaphore2->release();
+ tst_QMutex::semaphore3.release();
+ tst_QMutex::semaphore4.acquire();
}
}
};
@@ -249,24 +260,26 @@ void tst_QMutex::contendedNative()
QFETCH(int, iterations);
QFETCH(int, msleepDuration);
- QSemaphore semaphore1, semaphore2;
NativeMutexType mutex;
NativeMutexInitialize(&mutex);
QVector<NativeMutexThread *> threads(threadCount);
for (int i = 0; i < threads.count(); ++i) {
- threads[i] = new NativeMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration);
+ threads[i] = new NativeMutexThread(&mutex, iterations, msleepDuration);
threads[i]->start();
}
QBENCHMARK {
- semaphore1.release(threadCount);
- semaphore2.acquire(threadCount);
+ 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.release(threadCount);
+ semaphore1.acquire(threadCount);
+ semaphore2.release(threadCount);
for (int i = 0; i < threads.count(); ++i)
threads[i]->wait();
qDeleteAll(threads);
@@ -276,17 +289,17 @@ void tst_QMutex::contendedNative()
class QMutexThread : public QThread
{
- QSemaphore *semaphore1, *semaphore2;
QMutex *mutex;
int iterations, msleepDuration;
public:
bool done;
- QMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration)
- : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
+ QMutexThread(QMutex *mutex, int iterations, int msleepDuration)
+ : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
{ }
void run() {
forever {
- semaphore1->acquire();
+ tst_QMutex::semaphore1.release();
+ tst_QMutex::semaphore2.acquire();
if (done)
break;
for (int i = 0; i < iterations; ++i) {
@@ -294,8 +307,11 @@ public:
if (msleepDuration >= 0)
msleep(msleepDuration);
mutex->unlock();
+
+ QThread::yieldCurrentThread();
}
- semaphore2->release();
+ tst_QMutex::semaphore3.release();
+ tst_QMutex::semaphore4.acquire();
}
}
};
@@ -304,23 +320,26 @@ void tst_QMutex::contendedQMutex()
{
QFETCH(int, iterations);
QFETCH(int, msleepDuration);
- QSemaphore semaphore1, semaphore2;
+
QMutex mutex;
QVector<QMutexThread *> threads(threadCount);
for (int i = 0; i < threads.count(); ++i) {
- threads[i] = new QMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration);
+ threads[i] = new QMutexThread(&mutex, iterations, msleepDuration);
threads[i]->start();
}
QBENCHMARK {
- semaphore1.release(threadCount);
- semaphore2.acquire(threadCount);
+ 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.release(threadCount);
+ semaphore1.acquire(threadCount);
+ semaphore2.release(threadCount);
for (int i = 0; i < threads.count(); ++i)
threads[i]->wait();
qDeleteAll(threads);
@@ -328,25 +347,30 @@ void tst_QMutex::contendedQMutex()
class QMutexLockerThread : public QThread
{
- QSemaphore *semaphore1, *semaphore2;
QMutex *mutex;
int iterations, msleepDuration;
public:
bool done;
- QMutexLockerThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration)
- : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
+ QMutexLockerThread(QMutex *mutex, int iterations, int msleepDuration)
+ : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false)
{ }
void run() {
forever {
- semaphore1->acquire();
+ tst_QMutex::semaphore1.release();
+ tst_QMutex::semaphore2.acquire();
if (done)
break;
for (int i = 0; i < iterations; ++i) {
- QMutexLocker locker(mutex);
- if (msleepDuration >= 0)
- msleep(msleepDuration);
+ {
+ QMutexLocker locker(mutex1);
+ if (msleepDuration >= 0)
+ msleep(msleepDuration);
+ }
+
+ QThread::yieldCurrentThread();
}
- semaphore2->release();
+ tst_QMutex::semaphore3.release();
+ tst_QMutex::semaphore4.acquire();
}
}
};
@@ -355,23 +379,26 @@ void tst_QMutex::contendedQMutexLocker()
{
QFETCH(int, iterations);
QFETCH(int, msleepDuration);
- QSemaphore semaphore1, semaphore2;
+
QMutex mutex;
QVector<QMutexLockerThread *> threads(threadCount);
for (int i = 0; i < threads.count(); ++i) {
- threads[i] = new QMutexLockerThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration);
+ threads[i] = new QMutexLockerThread(&mutex, iterations, msleepDuration);
threads[i]->start();
}
QBENCHMARK {
- semaphore1.release(threadCount);
- semaphore2.acquire(threadCount);
+ 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.release(threadCount);
+ semaphore1.acquire(threadCount);
+ semaphore2.release(threadCount);
for (int i = 0; i < threads.count(); ++i)
threads[i]->wait();
qDeleteAll(threads);