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__); \
70 fail("%s | %s - %s", __FILE__, __FUNCTION__, why); \
71 return NS_ERROR_FAILURE; \
74 //-----------------------------------------------------------------------------
75 // Sanity check: tests that can be done on a single thread
80 Mutex
lock("sanity::lock");
82 lock
.AssertCurrentThreadOwns();
86 MutexAutoLock
autolock(lock
);
87 lock
.AssertCurrentThreadOwns();
91 lock
.AssertCurrentThreadOwns();
93 MutexAutoUnlock
autounlock(lock
);
95 lock
.AssertCurrentThreadOwns();
98 Monitor
mon("sanity::monitor");
100 mon
.AssertCurrentThreadIn();
102 mon
.AssertCurrentThreadIn();
104 mon
.AssertCurrentThreadIn();
108 MonitorAutoEnter
automon(mon
);
109 mon
.AssertCurrentThreadIn();
115 //-----------------------------------------------------------------------------
116 // Mutex contention tests
118 static Mutex
* gLock1
;
121 MutexContention_thread(void* /*arg*/)
123 for (int i
= 0; i
< 100000; ++i
) {
125 gLock1
->AssertCurrentThreadOwns();
133 gLock1
= new Mutex("lock1");
134 // PURPOSELY not checking for OOM. YAY!
136 PRThread
* t1
= spawn(MutexContention_thread
, nsnull
);
137 PRThread
* t2
= spawn(MutexContention_thread
, nsnull
);
138 PRThread
* t3
= spawn(MutexContention_thread
, nsnull
);
149 //-----------------------------------------------------------------------------
152 static Monitor
* gMon1
;
155 MonitorContention_thread(void* /*arg*/)
157 for (int i
= 0; i
< 100000; ++i
) {
159 gMon1
->AssertCurrentThreadIn();
167 gMon1
= new Monitor("mon1");
169 PRThread
* t1
= spawn(MonitorContention_thread
, nsnull
);
170 PRThread
* t2
= spawn(MonitorContention_thread
, nsnull
);
171 PRThread
* t3
= spawn(MonitorContention_thread
, nsnull
);
183 static Monitor
* gMon2
;
186 MonitorContention2_thread(void* /*arg*/)
188 for (int i
= 0; i
< 100000; ++i
) {
190 gMon2
->AssertCurrentThreadIn();
193 gMon2
->AssertCurrentThreadIn();
196 gMon2
->AssertCurrentThreadIn();
204 gMon2
= new Monitor("mon1");
206 PRThread
* t1
= spawn(MonitorContention2_thread
, nsnull
);
207 PRThread
* t2
= spawn(MonitorContention2_thread
, nsnull
);
208 PRThread
* t3
= spawn(MonitorContention2_thread
, nsnull
);
220 static Monitor
* gMon3
;
221 static PRInt32 gMonFirst
;
224 MonitorSyncSanity_thread(void* /*arg*/)
227 gMon3
->AssertCurrentThreadIn();
236 gMon3
->AssertCurrentThreadIn();
238 gMon3
->AssertCurrentThreadIn();
245 gMon3
= new Monitor("monitor::syncsanity");
247 for (PRInt32 i
= 0; i
< 10000; ++i
) {
249 PRThread
* ping
= spawn(MonitorSyncSanity_thread
, nsnull
);
250 PRThread
* pong
= spawn(MonitorSyncSanity_thread
, nsnull
);
260 //-----------------------------------------------------------------------------
263 static Mutex
* gCvlock1
;
264 static CondVar
* gCv1
;
265 static PRInt32 gCvFirst
;
268 CondVarSanity_thread(void* /*arg*/)
271 gCvlock1
->AssertCurrentThreadOwns();
278 gCvlock1
->AssertCurrentThreadOwns();
285 gCvlock1
= new Mutex("cvlock1");
286 gCv1
= new CondVar(*gCvlock1
, "cvlock1");
288 for (PRInt32 i
= 0; i
< 10000; ++i
) {
290 PRThread
* ping
= spawn(CondVarSanity_thread
, nsnull
);
291 PRThread
* pong
= spawn(CondVarSanity_thread
, nsnull
);
302 //-----------------------------------------------------------------------------
308 Mutex
l1("autolock");
309 MutexAutoLock
autol1(l1
);
311 l1
.AssertCurrentThreadOwns();
314 Mutex
l2("autolock2");
315 MutexAutoLock
autol2(l2
);
317 l1
.AssertCurrentThreadOwns();
318 l2
.AssertCurrentThreadOwns();
321 l1
.AssertCurrentThreadOwns();
326 //-----------------------------------------------------------------------------
332 Mutex
l1("autounlock");
333 Mutex
l2("autounlock2");
336 l1
.AssertCurrentThreadOwns();
339 MutexAutoUnlock
autol1(l1
);
342 l2
.AssertCurrentThreadOwns();
344 MutexAutoUnlock
autol2(l2
);
346 l2
.AssertCurrentThreadOwns();
349 l1
.AssertCurrentThreadOwns();
356 //-----------------------------------------------------------------------------
362 Monitor
m1("automonitor");
363 Monitor
m2("automonitor2");
366 m1
.AssertCurrentThreadIn();
368 MonitorAutoEnter
autom1(m1
);
369 m1
.AssertCurrentThreadIn();
372 m2
.AssertCurrentThreadIn();
374 MonitorAutoEnter
autom2(m2
);
375 m1
.AssertCurrentThreadIn();
376 m2
.AssertCurrentThreadIn();
378 m2
.AssertCurrentThreadIn();
381 m1
.AssertCurrentThreadIn();
383 m1
.AssertCurrentThreadIn();
389 //-----------------------------------------------------------------------------
392 main(int argc
, char** argv
)
394 ScopedXPCOM
xpcom("Synchronization (" __FILE__
")");
400 if (NS_FAILED(Sanity()))
402 if (NS_FAILED(MutexContention()))
404 if (NS_FAILED(MonitorContention()))
406 if (NS_FAILED(MonitorContention2()))
408 if (NS_FAILED(MonitorSyncSanity()))
410 if (NS_FAILED(CondVarSanity()))
412 if (NS_FAILED(AutoLock()))
414 if (NS_FAILED(AutoUnlock()))
416 if (NS_FAILED(AutoMonitor()))