static PRIntervalTime ReentrantMonitor(PRUint32 loops) { PRStatus status; PRThread *thread; PRMonitor *ml = PR_NewMonitor(); if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n"); PR_EnterMonitor(ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); PR_EnterMonitor(ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n"); thread = PR_CreateThread( PR_USER_THREAD, TryEntry, ml, PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); PR_ASSERT(thread != NULL); PR_Sleep(PR_SecondsToInterval(1)); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); PR_ExitMonitor(ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n"); PR_ExitMonitor(ml); if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n"); status = PR_JoinThread(thread); 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); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); contention->contender+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); PR_ExitMonitor(contention->ml); } } /* MonitorContender */
static void PR_CALLBACK TryEntry(void *arg) { PRMonitor *ml = (PRMonitor*)arg; if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n"); PR_EnterMonitor(ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n"); PR_ExitMonitor(ml); if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n"); } /* TryEntry */
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); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); contention->contentious+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); 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 */
/* * Notifies just get posted to the monitor. The actual notification is done * when the monitor is fully exited so that MP systems don't contend for a * monitor that they can't enter. */ static void pt_PostNotifyToMonitor(PRMonitor *mon, PRBool broadcast) { PR_ASSERT(NULL != mon); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mon); /* mon->notifyTimes is protected by the monitor, so we don't need to * acquire mon->lock. */ if (broadcast) mon->notifyTimes = -1; else if (-1 != mon->notifyTimes) mon->notifyTimes += 1; } /* pt_PostNotifyToMonitor */
static PRIntervalTime NonContentiousMonitor(PRUint32 loops) { PRMonitor *ml = NULL; ml = PR_NewMonitor(); while (loops-- > 0) { PR_EnterMonitor(ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); PR_ExitMonitor(ml); } PR_DestroyMonitor(ml); return 0; } /* NonContentiousMonitor */
static void tls13_AntiReplayUpdate() { PRTime now; PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ssl_anti_replay.lock); now = ssl_TimeUsec(); if (now < ssl_anti_replay.nextUpdate) { return; } tls13_AntiReplayRollover(now); }