1 /**
2 * Benchmark of different locking mechanisms; QMutex, PosixMutex, Silly
3 * (int-flag).
4 */
5
6 #include <QtCore>
7 #include <QtNetwork>
8
9 #include "Timer.h"
10
11 // It's important this is high enough the process doesn't complete in
12 // one timeslice.
13 #define ITER 100000000
14
15 typedef QPair<quint64,int> tr;
16
17 class SillyLock {
18 public:
19 int counter;
20 SillyLock();
21 void lock();
22 void unlock();
23 };
24
SillyLock()25 SillyLock::SillyLock() {
26 counter = 0;
27 }
28
lock()29 void SillyLock::lock() {
30 if (counter == 0)
31 counter = 1;
32 else
33 qFatal("Recursive lock");
34 }
35
unlock()36 void SillyLock::unlock() {
37 if (counter == 1)
38 counter = 0;
39 else
40 qFatal("Nonlock-unlock");
41 }
42
43 class PosixLock {
44 public:
45 pthread_mutex_t m;
46 PosixLock();
47 void lock();
48 void unlock();
49 };
50
PosixLock()51 PosixLock::PosixLock() {
52 pthread_mutex_init(&m, NULL);
53 }
54
lock()55 void PosixLock::lock() {
56 pthread_mutex_lock(&m);
57 }
58
unlock()59 void PosixLock::unlock() {
60 pthread_mutex_unlock(&m);
61 }
62
63 template<class T>
64 class SpeedTest {
65 public:
66 T &lock;
67
SpeedTest(T & l)68 SpeedTest(T &l) : lock(l) {
69 }
70
test()71 quint64 test() {
72 Timer t;
73 t.restart();
74 for (int i=0;i<ITER;i++) {
75 lock.lock();
76 lock.unlock();
77 }
78 return t.elapsed();
79 }
80 };
81
main(int argc,char ** argv)82 int main(int argc, char **argv) {
83 QCoreApplication a(argc, argv);
84
85 QMutex qm;
86 QMutex qmr(QMutex::Recursive);
87 SillyLock sl;
88 PosixLock pl;
89
90 SpeedTest<QMutex> stqm(qm);
91 SpeedTest<QMutex> stqmr(qmr);
92 SpeedTest<SillyLock> stsl(sl);
93 SpeedTest<PosixLock> stpl(pl);
94
95 quint64 elapsed;
96
97 elapsed = stsl.test();
98 qWarning("SillyLock: %8lld", elapsed);
99
100 elapsed = stqm.test();
101 qWarning("QMutex : %8lld", elapsed);
102
103 elapsed = stqmr.test();
104 qWarning("QMutexR : %8lld", elapsed);
105
106 elapsed = stpl.test();
107 qWarning("PosixLock: %8lld", elapsed);
108 }
109
110 // #include "Lock.moc"
111