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