1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Chris Jones <jones.chris.g@gmail.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "TestHarness.h"
42 #include "mozilla/CondVar.h"
43 #include "mozilla/Monitor.h"
44 #include "mozilla/Mutex.h"
45 #include "nsAutoLock.h"
47 using namespace mozilla
;
50 spawn(void (*run
)(void*), void* arg
)
52 return PR_CreateThread(PR_SYSTEM_THREAD
,
64 passed(__FUNCTION__); \
72 return NS_ERROR_FAILURE; \
75 //-----------------------------------------------------------------------------
76 // Sanity check: tests that can be done on a single thread
81 Mutex
lock("sanity::lock");
83 lock
.AssertCurrentThreadOwns();
87 MutexAutoLock
autolock(lock
);
88 lock
.AssertCurrentThreadOwns();
92 lock
.AssertCurrentThreadOwns();
94 MutexAutoUnlock
autounlock(lock
);
96 lock
.AssertCurrentThreadOwns();
99 Monitor
mon("sanity::monitor");
101 mon
.AssertCurrentThreadIn();
103 mon
.AssertCurrentThreadIn();
105 mon
.AssertCurrentThreadIn();
109 MonitorAutoEnter
automon(mon
);
110 mon
.AssertCurrentThreadIn();
116 //-----------------------------------------------------------------------------
117 // Mutex contention tests
119 static Mutex
* gLock1
;
122 MutexContention_thread(void* /*arg*/)
124 for (int i
= 0; i
< 100000; ++i
) {
126 gLock1
->AssertCurrentThreadOwns();
134 gLock1
= new Mutex("lock1");
135 // PURPOSELY not checking for OOM. YAY!
137 PRThread
* t1
= spawn(MutexContention_thread
, nsnull
);
138 PRThread
* t2
= spawn(MutexContention_thread
, nsnull
);
139 PRThread
* t3
= spawn(MutexContention_thread
, nsnull
);
150 //-----------------------------------------------------------------------------
153 static Monitor
* gMon1
;
156 MonitorContention_thread(void* /*arg*/)
158 for (int i
= 0; i
< 100000; ++i
) {
160 gMon1
->AssertCurrentThreadIn();
168 gMon1
= new Monitor("mon1");
170 PRThread
* t1
= spawn(MonitorContention_thread
, nsnull
);
171 PRThread
* t2
= spawn(MonitorContention_thread
, nsnull
);
172 PRThread
* t3
= spawn(MonitorContention_thread
, nsnull
);
184 static Monitor
* gMon2
;
187 MonitorContention2_thread(void* /*arg*/)
189 for (int i
= 0; i
< 100000; ++i
) {
191 gMon2
->AssertCurrentThreadIn();
194 gMon2
->AssertCurrentThreadIn();
197 gMon2
->AssertCurrentThreadIn();
205 gMon2
= new Monitor("mon1");
207 PRThread
* t1
= spawn(MonitorContention2_thread
, nsnull
);
208 PRThread
* t2
= spawn(MonitorContention2_thread
, nsnull
);
209 PRThread
* t3
= spawn(MonitorContention2_thread
, nsnull
);
221 static Monitor
* gMon3
;
222 static PRInt32 gMonFirst
;
225 MonitorSyncSanity_thread(void* /*arg*/)
228 gMon3
->AssertCurrentThreadIn();
237 gMon3
->AssertCurrentThreadIn();
239 gMon3
->AssertCurrentThreadIn();
246 gMon3
= new Monitor("monitor::syncsanity");
248 for (PRInt32 i
= 0; i
< 10000; ++i
) {
250 PRThread
* ping
= spawn(MonitorSyncSanity_thread
, nsnull
);
251 PRThread
* pong
= spawn(MonitorSyncSanity_thread
, nsnull
);
261 //-----------------------------------------------------------------------------
264 static Mutex
* gCvlock1
;
265 static CondVar
* gCv1
;
266 static PRInt32 gCvFirst
;
269 CondVarSanity_thread(void* /*arg*/)
272 gCvlock1
->AssertCurrentThreadOwns();
279 gCvlock1
->AssertCurrentThreadOwns();
286 gCvlock1
= new Mutex("cvlock1");
287 gCv1
= new CondVar(*gCvlock1
, "cvlock1");
289 for (PRInt32 i
= 0; i
< 10000; ++i
) {
291 PRThread
* ping
= spawn(CondVarSanity_thread
, nsnull
);
292 PRThread
* pong
= spawn(CondVarSanity_thread
, nsnull
);
303 //-----------------------------------------------------------------------------
309 Mutex
l1("autolock");
310 MutexAutoLock
autol1(l1
);
312 l1
.AssertCurrentThreadOwns();
315 Mutex
l2("autolock2");
316 MutexAutoLock
autol2(l2
);
318 l1
.AssertCurrentThreadOwns();
319 l2
.AssertCurrentThreadOwns();
322 l1
.AssertCurrentThreadOwns();
327 //-----------------------------------------------------------------------------
333 Mutex
l1("autounlock");
334 Mutex
l2("autounlock2");
337 l1
.AssertCurrentThreadOwns();
340 MutexAutoUnlock
autol1(l1
);
343 l2
.AssertCurrentThreadOwns();
345 MutexAutoUnlock
autol2(l2
);
347 l2
.AssertCurrentThreadOwns();
350 l1
.AssertCurrentThreadOwns();
357 //-----------------------------------------------------------------------------
363 Monitor
m1("automonitor");
364 Monitor
m2("automonitor2");
367 m1
.AssertCurrentThreadIn();
369 MonitorAutoEnter
autom1(m1
);
370 m1
.AssertCurrentThreadIn();
373 m2
.AssertCurrentThreadIn();
375 MonitorAutoEnter
autom2(m2
);
376 m1
.AssertCurrentThreadIn();
377 m2
.AssertCurrentThreadIn();
379 m2
.AssertCurrentThreadIn();
382 m1
.AssertCurrentThreadIn();
384 m1
.AssertCurrentThreadIn();
390 //-----------------------------------------------------------------------------
393 main(int argc
, char** argv
)
395 ScopedXPCOM
xpcom("Synchronization");
401 if (NS_FAILED(Sanity()))
403 if (NS_FAILED(MutexContention()))
405 if (NS_FAILED(MonitorContention()))
407 if (NS_FAILED(MonitorContention2()))
409 if (NS_FAILED(MonitorSyncSanity()))
411 if (NS_FAILED(CondVarSanity()))
413 if (NS_FAILED(AutoLock()))
415 if (NS_FAILED(AutoUnlock()))
417 if (NS_FAILED(AutoMonitor()))