📄 lock.c
字号:
if (debug_mode) PR_fprintf(std_err, "Reentrant thread joined %s\n", (status == PR_SUCCESS) ? "successfully" : "in error"); PR_DestroyMonitor(ml); return 0;} /* ReentrantMonitor */static void PR_CALLBACK MonitorContender(void *arg){ MonitorContentious_t *contention = (MonitorContentious_t*)arg; while (contention->loops-- > 0) { PR_EnterMonitor(contention->ml); contention->contender+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_ExitMonitor(contention->ml); }} /* MonitorContender */static PRUint32 ContentiousMonitor(PRUint32 loops){ PRStatus status; PRThread *thread = NULL; MonitorContentious_t * contention; PRIntervalTime rv, overhead, timein = PR_IntervalNow(); contention = PR_NEWZAP(MonitorContentious_t); contention->loops = loops; contention->overhead = 0; contention->ml = PR_NewMonitor(); contention->interval = contention_interval; thread = PR_CreateThread( PR_USER_THREAD, MonitorContender, contention, PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); PR_ASSERT(thread != NULL); overhead = PR_IntervalNow() - timein; while (contention->loops-- > 0) { PR_EnterMonitor(contention->ml); contention->contentious+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_ExitMonitor(contention->ml); } timein = PR_IntervalNow(); status = PR_JoinThread(thread); PR_DestroyMonitor(contention->ml); overhead += (PR_IntervalNow() - timein); rv = overhead + contention->overhead; if (verbosity) PR_fprintf( std_err, "Access ratio: %u to %u\n", contention->contentious, contention->contender); PR_Free(contention); return rv;} /* ContentiousMonitor *//*** CACHED MONITORS*/static PRIntervalTime NonContentiousCMonitor(PRUint32 loops){ MonitorContentious_t contention; while (loops-- > 0) { PR_CEnterMonitor(&contention); PR_CExitMonitor(&contention); } return 0;} /* NonContentiousCMonitor */static void PR_CALLBACK Contender(void *arg){ MonitorContentious_t *contention = (MonitorContentious_t*)arg; while (contention->loops-- > 0) { PR_CEnterMonitor(contention); contention->contender+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_CExitMonitor(contention); }} /* Contender */static PRIntervalTime ContentiousCMonitor(PRUint32 loops){ PRStatus status; PRThread *thread = NULL; MonitorContentious_t * contention; PRIntervalTime overhead, timein = PR_IntervalNow(); contention = PR_NEWZAP(MonitorContentious_t); contention->ml = NULL; contention->loops = loops; contention->interval = contention_interval; thread = PR_CreateThread( PR_USER_THREAD, Contender, contention, PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); PR_ASSERT(thread != NULL); overhead = PR_IntervalNow() - timein; while (contention->loops-- > 0) { PR_CEnterMonitor(contention); contention->contentious+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_CExitMonitor(contention); } timein = PR_IntervalNow(); status = PR_JoinThread(thread); overhead += (PR_IntervalNow() - timein); overhead += overhead + contention->overhead; if (verbosity) PR_fprintf( std_err, "Access ratio: %u to %u\n", contention->contentious, contention->contender); PR_Free(contention); return overhead;} /* ContentiousCMonitor */static PRIntervalTime Test( const char* msg, PRUint32 (*test)(PRUint32 loops), PRUint32 loops, PRIntervalTime overhead){ /* * overhead - overhead not measured by the test. * duration - wall clock time it took to perform test. * predicted - extra time test says should not be counted * * Time accountable to the test is duration - overhead - predicted * All times are Intervals and accumulated for all iterations. */ PRFloat64 elapsed; PRIntervalTime accountable, duration; PRUintn spaces = PL_strlen(msg); PRIntervalTime timeout, timein = PR_IntervalNow(); PRIntervalTime predicted = test(loops); timeout = PR_IntervalNow(); duration = timeout - timein; if (debug_mode) { accountable = duration - predicted; accountable -= overhead; elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable); PR_fprintf(PR_STDOUT, "%s:", msg); while (spaces++ < 50) PR_fprintf(PR_STDOUT, " "); if ((PRInt32)accountable < 0) PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n"); else PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops); } return duration;} /* Test */int main(int argc, char **argv){ PRBool rv = PR_TRUE; PRIntervalTime duration; PRUint32 cpu, cpus = 2, loops = 100; PR_STDIO_INIT(); PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); { /* The command line argument: -d is used to determine if the test is being run in debug mode. The regress tool requires only one line output:PASS or FAIL. All of the printfs associated with this test has been handled with a if (debug_mode) test. Command line argument -l <num> sets the number of loops. Command line argument -c <num> sets the number of cpus. Usage: lock [-d] [-l <num>] [-c <num>] */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = PR_TRUE; break; case 'v': /* debug mode */ verbosity = PR_TRUE; break; case 'l': /* number of loops */ loops = atoi(opt->value); break; case 'c': /* number of cpus */ cpus = atoi(opt->value); break; default: break; } } PL_DestroyOptState(opt); } /* main test */ PR_SetConcurrency(8);#ifdef XP_MAC SetupMacPrintfLog("lock.log"); debug_mode = 1;#endif if (loops == 0) loops = 100; if (debug_mode) { std_err = PR_STDERR; PR_fprintf(std_err, "Lock: Using %d loops\n", loops); } if (cpus == 0) cpus = 2; if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus); (void)Sleeper(10); /* try filling in the caches */ for (cpu = 1; cpu <= cpus; ++cpu) { if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu); PR_SetConcurrency(cpu); duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0); duration = 0; (void)Test("Lock creation/deletion", MakeLock, loops, 0); (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0); (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration); (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0); (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0); (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration); (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0); (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration); (void)ReentrantMonitor(loops); } if (debug_mode) PR_fprintf( std_err, "%s: test %s\n", "Lock(mutex) test", ((rv) ? "passed" : "failed")); else { if (!rv) failed_already=1; } if(failed_already) { PR_fprintf(PR_STDOUT, "FAIL\n"); return 1; } else { PR_fprintf(PR_STDOUT, "PASS\n"); return 0; }} /* main *//* testlock.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -