1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "TestHarness.h"
9 #include "mozilla/CondVar.h"
10 #include "mozilla/Monitor.h"
11 #include "mozilla/Mutex.h"
12 #include "nsAutoLock.h"
14 using namespace mozilla
;
17 spawn(void (*run
)(void*), void* arg
)
19 return PR_CreateThread(PR_SYSTEM_THREAD
,
31 passed(__FUNCTION__); \
37 fail("%s | %s - %s", __FILE__, __FUNCTION__, why); \
38 return NS_ERROR_FAILURE; \
41 //-----------------------------------------------------------------------------
42 // Sanity check: tests that can be done on a single thread
47 Mutex
lock("sanity::lock");
49 lock
.AssertCurrentThreadOwns();
53 MutexAutoLock
autolock(lock
);
54 lock
.AssertCurrentThreadOwns();
58 lock
.AssertCurrentThreadOwns();
60 MutexAutoUnlock
autounlock(lock
);
62 lock
.AssertCurrentThreadOwns();
65 Monitor
mon("sanity::monitor");
67 mon
.AssertCurrentThreadIn();
69 mon
.AssertCurrentThreadIn();
71 mon
.AssertCurrentThreadIn();
75 MonitorAutoEnter
automon(mon
);
76 mon
.AssertCurrentThreadIn();
82 //-----------------------------------------------------------------------------
83 // Mutex contention tests
88 MutexContention_thread(void* /*arg*/)
90 for (int i
= 0; i
< 100000; ++i
) {
92 gLock1
->AssertCurrentThreadOwns();
100 gLock1
= new Mutex("lock1");
101 // PURPOSELY not checking for OOM. YAY!
103 PRThread
* t1
= spawn(MutexContention_thread
, nullptr);
104 PRThread
* t2
= spawn(MutexContention_thread
, nullptr);
105 PRThread
* t3
= spawn(MutexContention_thread
, nullptr);
116 //-----------------------------------------------------------------------------
119 static Monitor
* gMon1
;
122 MonitorContention_thread(void* /*arg*/)
124 for (int i
= 0; i
< 100000; ++i
) {
126 gMon1
->AssertCurrentThreadIn();
134 gMon1
= new Monitor("mon1");
136 PRThread
* t1
= spawn(MonitorContention_thread
, nullptr);
137 PRThread
* t2
= spawn(MonitorContention_thread
, nullptr);
138 PRThread
* t3
= spawn(MonitorContention_thread
, nullptr);
150 static Monitor
* gMon2
;
153 MonitorContention2_thread(void* /*arg*/)
155 for (int i
= 0; i
< 100000; ++i
) {
157 gMon2
->AssertCurrentThreadIn();
160 gMon2
->AssertCurrentThreadIn();
163 gMon2
->AssertCurrentThreadIn();
171 gMon2
= new Monitor("mon1");
173 PRThread
* t1
= spawn(MonitorContention2_thread
, nullptr);
174 PRThread
* t2
= spawn(MonitorContention2_thread
, nullptr);
175 PRThread
* t3
= spawn(MonitorContention2_thread
, nullptr);
187 static Monitor
* gMon3
;
188 static int32_t gMonFirst
;
191 MonitorSyncSanity_thread(void* /*arg*/)
194 gMon3
->AssertCurrentThreadIn();
203 gMon3
->AssertCurrentThreadIn();
205 gMon3
->AssertCurrentThreadIn();
212 gMon3
= new Monitor("monitor::syncsanity");
214 for (int32_t i
= 0; i
< 10000; ++i
) {
216 PRThread
* ping
= spawn(MonitorSyncSanity_thread
, nullptr);
217 PRThread
* pong
= spawn(MonitorSyncSanity_thread
, nullptr);
227 //-----------------------------------------------------------------------------
230 static Mutex
* gCvlock1
;
231 static CondVar
* gCv1
;
232 static int32_t gCvFirst
;
235 CondVarSanity_thread(void* /*arg*/)
238 gCvlock1
->AssertCurrentThreadOwns();
245 gCvlock1
->AssertCurrentThreadOwns();
252 gCvlock1
= new Mutex("cvlock1");
253 gCv1
= new CondVar(*gCvlock1
, "cvlock1");
255 for (int32_t i
= 0; i
< 10000; ++i
) {
257 PRThread
* ping
= spawn(CondVarSanity_thread
, nullptr);
258 PRThread
* pong
= spawn(CondVarSanity_thread
, nullptr);
269 //-----------------------------------------------------------------------------
275 Mutex
l1("autolock");
276 MutexAutoLock
autol1(l1
);
278 l1
.AssertCurrentThreadOwns();
281 Mutex
l2("autolock2");
282 MutexAutoLock
autol2(l2
);
284 l1
.AssertCurrentThreadOwns();
285 l2
.AssertCurrentThreadOwns();
288 l1
.AssertCurrentThreadOwns();
293 //-----------------------------------------------------------------------------
299 Mutex
l1("autounlock");
300 Mutex
l2("autounlock2");
303 l1
.AssertCurrentThreadOwns();
306 MutexAutoUnlock
autol1(l1
);
309 l2
.AssertCurrentThreadOwns();
311 MutexAutoUnlock
autol2(l2
);
313 l2
.AssertCurrentThreadOwns();
316 l1
.AssertCurrentThreadOwns();
323 //-----------------------------------------------------------------------------
329 Monitor
m1("automonitor");
330 Monitor
m2("automonitor2");
333 m1
.AssertCurrentThreadIn();
335 MonitorAutoEnter
autom1(m1
);
336 m1
.AssertCurrentThreadIn();
339 m2
.AssertCurrentThreadIn();
341 MonitorAutoEnter
autom2(m2
);
342 m1
.AssertCurrentThreadIn();
343 m2
.AssertCurrentThreadIn();
345 m2
.AssertCurrentThreadIn();
348 m1
.AssertCurrentThreadIn();
350 m1
.AssertCurrentThreadIn();
356 //-----------------------------------------------------------------------------
359 main(int argc
, char** argv
)
361 ScopedXPCOM
xpcom("Synchronization (" __FILE__
")");
367 if (NS_FAILED(Sanity()))
369 if (NS_FAILED(MutexContention()))
371 if (NS_FAILED(MonitorContention()))
373 if (NS_FAILED(MonitorContention2()))
375 if (NS_FAILED(MonitorSyncSanity()))
377 if (NS_FAILED(CondVarSanity()))
379 if (NS_FAILED(AutoLock()))
381 if (NS_FAILED(AutoUnlock()))
383 if (NS_FAILED(AutoMonitor()))