nsprpub/pr/tests/lock.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 ** File: lock.c
michael@0 8 ** Purpose: test basic locking functions
michael@0 9 **
michael@0 10 ** Modification History:
michael@0 11 ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
michael@0 12 ** The debug mode will print all of the printfs associated with this test.
michael@0 13 ** The regress mode will be the default mode. Since the regress tool limits
michael@0 14 ** the output to a one line status:PASS or FAIL,all of the printf statements
michael@0 15 ** have been handled with an if (debug_mode) statement.
michael@0 16 ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
michael@0 17 ** recognize the return code from tha main program.
michael@0 18 **
michael@0 19 ** 11-Aug-97 LarryH. Win16 port of NSPR.
michael@0 20 ** - Added "PASS", "FAIL" messages on completion.
michael@0 21 ** - Change stack variables to static scope variables
michael@0 22 ** because of shadow-stack use by Win16
michael@0 23 ** - Added PR_CALLBACK attribute to functions called by NSPR
michael@0 24 ** - Added command line arguments:
michael@0 25 ** - l <num> to control the number of loops
michael@0 26 ** - c <num> to control the number of CPUs.
michael@0 27 ** (was positional argv).
michael@0 28 **
michael@0 29 **
michael@0 30 ***********************************************************************/
michael@0 31
michael@0 32 /***********************************************************************
michael@0 33 ** Includes
michael@0 34 ***********************************************************************/
michael@0 35 /* Used to get the command line option */
michael@0 36 #include "plgetopt.h"
michael@0 37
michael@0 38 #include "prio.h"
michael@0 39 #include "prcmon.h"
michael@0 40 #include "prinit.h"
michael@0 41 #include "prinrval.h"
michael@0 42 #include "prprf.h"
michael@0 43 #include "prlock.h"
michael@0 44 #include "prlog.h"
michael@0 45 #include "prmon.h"
michael@0 46 #include "prmem.h"
michael@0 47 #include "prthread.h"
michael@0 48 #include "prtypes.h"
michael@0 49
michael@0 50 #include "plstr.h"
michael@0 51
michael@0 52 #include <stdlib.h>
michael@0 53
michael@0 54 #if defined(XP_UNIX)
michael@0 55 #include <string.h>
michael@0 56 #endif
michael@0 57
michael@0 58 static PRIntn failed_already=0;
michael@0 59 static PRFileDesc *std_err = NULL;
michael@0 60 static PRBool verbosity = PR_FALSE;
michael@0 61 static PRBool debug_mode = PR_FALSE;
michael@0 62
michael@0 63 const static PRIntervalTime contention_interval = 50;
michael@0 64
michael@0 65 typedef struct LockContentious_s {
michael@0 66 PRLock *ml;
michael@0 67 PRInt32 loops;
michael@0 68 PRUint32 contender;
michael@0 69 PRUint32 contentious;
michael@0 70 PRIntervalTime overhead;
michael@0 71 PRIntervalTime interval;
michael@0 72 } LockContentious_t;
michael@0 73
michael@0 74 typedef struct MonitorContentious_s {
michael@0 75 PRMonitor *ml;
michael@0 76 PRInt32 loops;
michael@0 77 PRUint32 contender;
michael@0 78 PRUint32 contentious;
michael@0 79 PRIntervalTime overhead;
michael@0 80 PRIntervalTime interval;
michael@0 81 } MonitorContentious_t;
michael@0 82
michael@0 83
michael@0 84 static PRIntervalTime Sleeper(PRUint32 loops)
michael@0 85 {
michael@0 86 PRIntervalTime predicted = 0;
michael@0 87 while (loops-- > 0)
michael@0 88 {
michael@0 89 predicted += contention_interval;
michael@0 90 (void)PR_Sleep(contention_interval);
michael@0 91 }
michael@0 92 return predicted;
michael@0 93 } /* Sleeper */
michael@0 94
michael@0 95 /*
michael@0 96 ** BASIC LOCKS
michael@0 97 */
michael@0 98 static PRIntervalTime MakeLock(PRUint32 loops)
michael@0 99 {
michael@0 100 PRLock *ml = NULL;
michael@0 101 while (loops-- > 0)
michael@0 102 {
michael@0 103 ml = PR_NewLock();
michael@0 104 PR_DestroyLock(ml);
michael@0 105 ml = NULL;
michael@0 106 }
michael@0 107 return 0;
michael@0 108 } /* MakeLock */
michael@0 109
michael@0 110 static PRIntervalTime NonContentiousLock(PRUint32 loops)
michael@0 111 {
michael@0 112 PRLock *ml = NULL;
michael@0 113 ml = PR_NewLock();
michael@0 114 while (loops-- > 0)
michael@0 115 {
michael@0 116 PR_Lock(ml);
michael@0 117 PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(ml);
michael@0 118 PR_Unlock(ml);
michael@0 119 }
michael@0 120 PR_DestroyLock(ml);
michael@0 121 return 0;
michael@0 122 } /* NonContentiousLock */
michael@0 123
michael@0 124 static void PR_CALLBACK LockContender(void *arg)
michael@0 125 {
michael@0 126 LockContentious_t *contention = (LockContentious_t*)arg;
michael@0 127 while (contention->loops-- > 0)
michael@0 128 {
michael@0 129 PR_Lock(contention->ml);
michael@0 130 PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
michael@0 131 contention->contender+= 1;
michael@0 132 contention->overhead += contention->interval;
michael@0 133 PR_Sleep(contention->interval);
michael@0 134 PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
michael@0 135 PR_Unlock(contention->ml);
michael@0 136 }
michael@0 137 } /* LockContender */
michael@0 138
michael@0 139 static PRIntervalTime ContentiousLock(PRUint32 loops)
michael@0 140 {
michael@0 141 PRStatus status;
michael@0 142 PRThread *thread = NULL;
michael@0 143 LockContentious_t * contention;
michael@0 144 PRIntervalTime rv, overhead, timein = PR_IntervalNow();
michael@0 145
michael@0 146 contention = PR_NEWZAP(LockContentious_t);
michael@0 147 contention->loops = loops;
michael@0 148 contention->overhead = 0;
michael@0 149 contention->ml = PR_NewLock();
michael@0 150 contention->interval = contention_interval;
michael@0 151 thread = PR_CreateThread(
michael@0 152 PR_USER_THREAD, LockContender, contention,
michael@0 153 PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
michael@0 154 PR_ASSERT(thread != NULL);
michael@0 155
michael@0 156 overhead = PR_IntervalNow() - timein;
michael@0 157
michael@0 158 while (contention->loops-- > 0)
michael@0 159 {
michael@0 160 PR_Lock(contention->ml);
michael@0 161 PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
michael@0 162 contention->contentious+= 1;
michael@0 163 contention->overhead += contention->interval;
michael@0 164 PR_Sleep(contention->interval);
michael@0 165 PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
michael@0 166 PR_Unlock(contention->ml);
michael@0 167 }
michael@0 168
michael@0 169 timein = PR_IntervalNow();
michael@0 170 status = PR_JoinThread(thread);
michael@0 171 PR_DestroyLock(contention->ml);
michael@0 172 overhead += (PR_IntervalNow() - timein);
michael@0 173 rv = overhead + contention->overhead;
michael@0 174 if (verbosity)
michael@0 175 PR_fprintf(
michael@0 176 std_err, "Access ratio: %u to %u\n",
michael@0 177 contention->contentious, contention->contender);
michael@0 178 PR_Free(contention);
michael@0 179 return rv;
michael@0 180 } /* ContentiousLock */
michael@0 181
michael@0 182 /*
michael@0 183 ** MONITORS
michael@0 184 */
michael@0 185 static PRIntervalTime MakeMonitor(PRUint32 loops)
michael@0 186 {
michael@0 187 PRMonitor *ml = NULL;
michael@0 188 while (loops-- > 0)
michael@0 189 {
michael@0 190 ml = PR_NewMonitor();
michael@0 191 PR_DestroyMonitor(ml);
michael@0 192 ml = NULL;
michael@0 193 }
michael@0 194 return 0;
michael@0 195 } /* MakeMonitor */
michael@0 196
michael@0 197 static PRIntervalTime NonContentiousMonitor(PRUint32 loops)
michael@0 198 {
michael@0 199 PRMonitor *ml = NULL;
michael@0 200 ml = PR_NewMonitor();
michael@0 201 while (loops-- > 0)
michael@0 202 {
michael@0 203 PR_EnterMonitor(ml);
michael@0 204 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 205 PR_ExitMonitor(ml);
michael@0 206 }
michael@0 207 PR_DestroyMonitor(ml);
michael@0 208 return 0;
michael@0 209 } /* NonContentiousMonitor */
michael@0 210
michael@0 211 static void PR_CALLBACK TryEntry(void *arg)
michael@0 212 {
michael@0 213 PRMonitor *ml = (PRMonitor*)arg;
michael@0 214 if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n");
michael@0 215 PR_EnterMonitor(ml);
michael@0 216 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 217 if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n");
michael@0 218 PR_ExitMonitor(ml);
michael@0 219 if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n");
michael@0 220 } /* TryEntry */
michael@0 221
michael@0 222 static PRIntervalTime ReentrantMonitor(PRUint32 loops)
michael@0 223 {
michael@0 224 PRStatus status;
michael@0 225 PRThread *thread;
michael@0 226 PRMonitor *ml = PR_NewMonitor();
michael@0 227 if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n");
michael@0 228
michael@0 229 PR_EnterMonitor(ml);
michael@0 230 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 231 PR_EnterMonitor(ml);
michael@0 232 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 233 if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n");
michael@0 234
michael@0 235 thread = PR_CreateThread(
michael@0 236 PR_USER_THREAD, TryEntry, ml,
michael@0 237 PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
michael@0 238 PR_ASSERT(thread != NULL);
michael@0 239 PR_Sleep(PR_SecondsToInterval(1));
michael@0 240 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 241
michael@0 242 PR_ExitMonitor(ml);
michael@0 243 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
michael@0 244 if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n");
michael@0 245
michael@0 246 PR_ExitMonitor(ml);
michael@0 247 if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n");
michael@0 248
michael@0 249 status = PR_JoinThread(thread);
michael@0 250 if (debug_mode) PR_fprintf(std_err,
michael@0 251 "Reentrant thread joined %s\n",
michael@0 252 (status == PR_SUCCESS) ? "successfully" : "in error");
michael@0 253
michael@0 254 PR_DestroyMonitor(ml);
michael@0 255 return 0;
michael@0 256 } /* ReentrantMonitor */
michael@0 257
michael@0 258 static void PR_CALLBACK MonitorContender(void *arg)
michael@0 259 {
michael@0 260 MonitorContentious_t *contention = (MonitorContentious_t*)arg;
michael@0 261 while (contention->loops-- > 0)
michael@0 262 {
michael@0 263 PR_EnterMonitor(contention->ml);
michael@0 264 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
michael@0 265 contention->contender+= 1;
michael@0 266 contention->overhead += contention->interval;
michael@0 267 PR_Sleep(contention->interval);
michael@0 268 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
michael@0 269 PR_ExitMonitor(contention->ml);
michael@0 270 }
michael@0 271 } /* MonitorContender */
michael@0 272
michael@0 273 static PRUint32 ContentiousMonitor(PRUint32 loops)
michael@0 274 {
michael@0 275 PRStatus status;
michael@0 276 PRThread *thread = NULL;
michael@0 277 MonitorContentious_t * contention;
michael@0 278 PRIntervalTime rv, overhead, timein = PR_IntervalNow();
michael@0 279
michael@0 280 contention = PR_NEWZAP(MonitorContentious_t);
michael@0 281 contention->loops = loops;
michael@0 282 contention->overhead = 0;
michael@0 283 contention->ml = PR_NewMonitor();
michael@0 284 contention->interval = contention_interval;
michael@0 285 thread = PR_CreateThread(
michael@0 286 PR_USER_THREAD, MonitorContender, contention,
michael@0 287 PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
michael@0 288 PR_ASSERT(thread != NULL);
michael@0 289
michael@0 290 overhead = PR_IntervalNow() - timein;
michael@0 291
michael@0 292 while (contention->loops-- > 0)
michael@0 293 {
michael@0 294 PR_EnterMonitor(contention->ml);
michael@0 295 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
michael@0 296 contention->contentious+= 1;
michael@0 297 contention->overhead += contention->interval;
michael@0 298 PR_Sleep(contention->interval);
michael@0 299 PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
michael@0 300 PR_ExitMonitor(contention->ml);
michael@0 301 }
michael@0 302
michael@0 303 timein = PR_IntervalNow();
michael@0 304 status = PR_JoinThread(thread);
michael@0 305 PR_DestroyMonitor(contention->ml);
michael@0 306 overhead += (PR_IntervalNow() - timein);
michael@0 307 rv = overhead + contention->overhead;
michael@0 308 if (verbosity)
michael@0 309 PR_fprintf(
michael@0 310 std_err, "Access ratio: %u to %u\n",
michael@0 311 contention->contentious, contention->contender);
michael@0 312 PR_Free(contention);
michael@0 313 return rv;
michael@0 314 } /* ContentiousMonitor */
michael@0 315
michael@0 316 /*
michael@0 317 ** CACHED MONITORS
michael@0 318 */
michael@0 319 static PRIntervalTime NonContentiousCMonitor(PRUint32 loops)
michael@0 320 {
michael@0 321 MonitorContentious_t contention;
michael@0 322 while (loops-- > 0)
michael@0 323 {
michael@0 324 PR_CEnterMonitor(&contention);
michael@0 325 PR_CExitMonitor(&contention);
michael@0 326 }
michael@0 327 return 0;
michael@0 328 } /* NonContentiousCMonitor */
michael@0 329
michael@0 330 static void PR_CALLBACK Contender(void *arg)
michael@0 331 {
michael@0 332 MonitorContentious_t *contention = (MonitorContentious_t*)arg;
michael@0 333 while (contention->loops-- > 0)
michael@0 334 {
michael@0 335 PR_CEnterMonitor(contention);
michael@0 336 contention->contender+= 1;
michael@0 337 contention->overhead += contention->interval;
michael@0 338 PR_Sleep(contention->interval);
michael@0 339 PR_CExitMonitor(contention);
michael@0 340 }
michael@0 341 } /* Contender */
michael@0 342
michael@0 343 static PRIntervalTime ContentiousCMonitor(PRUint32 loops)
michael@0 344 {
michael@0 345 PRStatus status;
michael@0 346 PRThread *thread = NULL;
michael@0 347 MonitorContentious_t * contention;
michael@0 348 PRIntervalTime overhead, timein = PR_IntervalNow();
michael@0 349
michael@0 350 contention = PR_NEWZAP(MonitorContentious_t);
michael@0 351 contention->ml = NULL;
michael@0 352 contention->loops = loops;
michael@0 353 contention->interval = contention_interval;
michael@0 354 thread = PR_CreateThread(
michael@0 355 PR_USER_THREAD, Contender, contention,
michael@0 356 PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
michael@0 357 PR_ASSERT(thread != NULL);
michael@0 358
michael@0 359 overhead = PR_IntervalNow() - timein;
michael@0 360
michael@0 361 while (contention->loops-- > 0)
michael@0 362 {
michael@0 363 PR_CEnterMonitor(contention);
michael@0 364 contention->contentious+= 1;
michael@0 365 contention->overhead += contention->interval;
michael@0 366 PR_Sleep(contention->interval);
michael@0 367 PR_CExitMonitor(contention);
michael@0 368 }
michael@0 369
michael@0 370 timein = PR_IntervalNow();
michael@0 371 status = PR_JoinThread(thread);
michael@0 372 overhead += (PR_IntervalNow() - timein);
michael@0 373 overhead += overhead + contention->overhead;
michael@0 374 if (verbosity)
michael@0 375 PR_fprintf(
michael@0 376 std_err, "Access ratio: %u to %u\n",
michael@0 377 contention->contentious, contention->contender);
michael@0 378 PR_Free(contention);
michael@0 379 return overhead;
michael@0 380 } /* ContentiousCMonitor */
michael@0 381
michael@0 382 static PRIntervalTime Test(
michael@0 383 const char* msg, PRUint32 (*test)(PRUint32 loops),
michael@0 384 PRUint32 loops, PRIntervalTime overhead)
michael@0 385 {
michael@0 386 /*
michael@0 387 * overhead - overhead not measured by the test.
michael@0 388 * duration - wall clock time it took to perform test.
michael@0 389 * predicted - extra time test says should not be counted
michael@0 390 *
michael@0 391 * Time accountable to the test is duration - overhead - predicted
michael@0 392 * All times are Intervals and accumulated for all iterations.
michael@0 393 */
michael@0 394 PRFloat64 elapsed;
michael@0 395 PRIntervalTime accountable, duration;
michael@0 396 PRUintn spaces = PL_strlen(msg);
michael@0 397 PRIntervalTime timeout, timein = PR_IntervalNow();
michael@0 398 PRIntervalTime predicted = test(loops);
michael@0 399 timeout = PR_IntervalNow();
michael@0 400 duration = timeout - timein;
michael@0 401
michael@0 402 if (debug_mode)
michael@0 403 {
michael@0 404 accountable = duration - predicted;
michael@0 405 accountable -= overhead;
michael@0 406 elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
michael@0 407 PR_fprintf(PR_STDOUT, "%s:", msg);
michael@0 408 while (spaces++ < 50) PR_fprintf(PR_STDOUT, " ");
michael@0 409 if ((PRInt32)accountable < 0)
michael@0 410 PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n");
michael@0 411 else
michael@0 412 PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops);
michael@0 413 }
michael@0 414 return duration;
michael@0 415 } /* Test */
michael@0 416
michael@0 417 int main(int argc, char **argv)
michael@0 418 {
michael@0 419 PRBool rv = PR_TRUE;
michael@0 420 PRIntervalTime duration;
michael@0 421 PRUint32 cpu, cpus = 2, loops = 100;
michael@0 422
michael@0 423
michael@0 424 PR_STDIO_INIT();
michael@0 425 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
michael@0 426 {
michael@0 427 /* The command line argument: -d is used to determine if the test is being run
michael@0 428 in debug mode. The regress tool requires only one line output:PASS or FAIL.
michael@0 429 All of the printfs associated with this test has been handled with a if (debug_mode)
michael@0 430 test.
michael@0 431 Command line argument -l <num> sets the number of loops.
michael@0 432 Command line argument -c <num> sets the number of cpus.
michael@0 433 Usage: lock [-d] [-l <num>] [-c <num>]
michael@0 434 */
michael@0 435 PLOptStatus os;
michael@0 436 PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:");
michael@0 437 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
michael@0 438 {
michael@0 439 if (PL_OPT_BAD == os) continue;
michael@0 440 switch (opt->option)
michael@0 441 {
michael@0 442 case 'd': /* debug mode */
michael@0 443 debug_mode = PR_TRUE;
michael@0 444 break;
michael@0 445 case 'v': /* debug mode */
michael@0 446 verbosity = PR_TRUE;
michael@0 447 break;
michael@0 448 case 'l': /* number of loops */
michael@0 449 loops = atoi(opt->value);
michael@0 450 break;
michael@0 451 case 'c': /* number of cpus */
michael@0 452 cpus = atoi(opt->value);
michael@0 453 break;
michael@0 454 default:
michael@0 455 break;
michael@0 456 }
michael@0 457 }
michael@0 458 PL_DestroyOptState(opt);
michael@0 459 }
michael@0 460
michael@0 461 /* main test */
michael@0 462 PR_SetConcurrency(8);
michael@0 463
michael@0 464 if (loops == 0) loops = 100;
michael@0 465 if (debug_mode)
michael@0 466 {
michael@0 467 std_err = PR_STDERR;
michael@0 468 PR_fprintf(std_err, "Lock: Using %d loops\n", loops);
michael@0 469 }
michael@0 470
michael@0 471 if (cpus == 0) cpus = 2;
michael@0 472 if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus);
michael@0 473
michael@0 474 (void)Sleeper(10); /* try filling in the caches */
michael@0 475
michael@0 476 for (cpu = 1; cpu <= cpus; ++cpu)
michael@0 477 {
michael@0 478 if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu);
michael@0 479 PR_SetConcurrency(cpu);
michael@0 480
michael@0 481 duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0);
michael@0 482 duration = 0;
michael@0 483
michael@0 484 (void)Test("Lock creation/deletion", MakeLock, loops, 0);
michael@0 485 (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0);
michael@0 486 (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration);
michael@0 487 (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0);
michael@0 488 (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0);
michael@0 489 (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration);
michael@0 490
michael@0 491 (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0);
michael@0 492 (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration);
michael@0 493
michael@0 494 (void)ReentrantMonitor(loops);
michael@0 495 }
michael@0 496
michael@0 497 if (debug_mode)
michael@0 498 PR_fprintf(
michael@0 499 std_err, "%s: test %s\n", "Lock(mutex) test",
michael@0 500 ((rv) ? "passed" : "failed"));
michael@0 501 else {
michael@0 502 if (!rv)
michael@0 503 failed_already=1;
michael@0 504 }
michael@0 505
michael@0 506 if(failed_already)
michael@0 507 {
michael@0 508 PR_fprintf(PR_STDOUT, "FAIL\n");
michael@0 509 return 1;
michael@0 510 }
michael@0 511 else
michael@0 512 {
michael@0 513 PR_fprintf(PR_STDOUT, "PASS\n");
michael@0 514 return 0;
michael@0 515 }
michael@0 516
michael@0 517 } /* main */
michael@0 518
michael@0 519 /* testlock.c */

mercurial