diff options
author | sfraser%netscape.com <devnull@localhost> | 2002-07-10 01:09:29 +0000 |
---|---|---|
committer | sfraser%netscape.com <devnull@localhost> | 2002-07-10 01:09:29 +0000 |
commit | ad451f67def65af7d041ee3bd84023020d2ddc2f (patch) | |
tree | a5eacdda2bb693496669851d05582183685c149a | |
parent | d09c73a8a0449e8f5b6b1dc5fb0010cefeebc376 (diff) | |
download | nspr-hg-ad451f67def65af7d041ee3bd84023020d2ddc2f.tar.gz |
Fix for bug 139802; slow certificate authentication on Mac OS X. This was caused by the application spending lots of time in WaitNextEvent, called from its main event loop (which is a good thing, in terms of CPU usage). The problem is that NSPR threads then don't get enough time. This patch give the process scheduler a kick in the pants when NSPR is going to switch to another of its threads. r=wtc, r=sdagley
-rw-r--r-- | pr/src/md/mac/macthr.c | 30 | ||||
-rw-r--r-- | pr/src/md/mac/mdmac.c | 3 |
2 files changed, 26 insertions, 7 deletions
diff --git a/pr/src/md/mac/macthr.c b/pr/src/md/mac/macthr.c index e84e38a2..6a1f18d4 100644 --- a/pr/src/md/mac/macthr.c +++ b/pr/src/md/mac/macthr.c @@ -49,6 +49,8 @@ TimerUPP gTimerCallbackUPP = NULL; PRThread * gPrimaryThread = NULL; +ProcessSerialNumber gApplicationProcess; + PR_IMPLEMENT(PRThread *) PR_GetPrimaryThread() { return gPrimaryThread; @@ -159,7 +161,21 @@ extern void _MD_ClearStack(PRThreadStack *ts) #pragma mark - #pragma mark TIME MANAGER-BASED CLOCK -TMTask gTimeManagerTaskElem; +// On Mac OS X, it's possible for the application to spend lots of time +// in WaitNextEvent, yielding to other applications. Since NSPR threads are +// cooperative here, this means that NSPR threads will also get very little +// time to run. To kick ourselves out of a WaitNextEvent call when we have +// determined that it's time to schedule another thread, the Timer Task +// (which fires every 8ms, even when other apps have the CPU) calls WakeUpProcess. +// We only want to do this on Mac OS X; the gTimeManagerTaskDoesWUP variable +// indicates when we're running on that OS. +// +// Note that the TimerCallback makes use of gApplicationProcess. We need to +// have set this up before the first possible run of the timer task; we do +// so in _MD_EarlyInit(). +static Boolean gTimeManagerTaskDoesWUP; + +static TMTask gTimeManagerTaskElem; extern void _MD_IOInterrupt(void); _PRInterruptTable _pr_interruptTable[] = { @@ -184,8 +200,11 @@ pascal void TimerCallback(TMTaskPtr tmTaskPtr) // And tell nspr that a clock interrupt occured. _PR_ClockInterrupt(); - if ((_PR_RUNQREADYMASK(cpu)) >> ((_PR_MD_CURRENT_THREAD()->priority))) + if ((_PR_RUNQREADYMASK(cpu)) >> ((_PR_MD_CURRENT_THREAD()->priority))) { + if (gTimeManagerTaskDoesWUP) + WakeUpProcess(&gApplicationProcess); _PR_SET_RESCHED_FLAG(); + } _PR_FAST_INTSON(is); @@ -198,6 +217,8 @@ void _MD_StartInterrupts(void) { gPrimaryThread = _PR_MD_CURRENT_THREAD(); + gTimeManagerTaskDoesWUP = RunningOnOSX(); + if ( !gTimerCallbackUPP ) gTimerCallbackUPP = NewTimerUPP(TimerCallback); @@ -607,7 +628,6 @@ void LeaveCritialRegion() PRBool gUseIdleSemaphore = PR_FALSE; MPSemaphoreID gIdleSemaphore = NULL; #endif -ProcessSerialNumber gApplicationProcess; void InitIdleSemaphore() { @@ -619,11 +639,7 @@ void InitIdleSemaphore() OSStatus err = MPCreateSemaphore(1 /* max value */, 0 /* initial value */, &gIdleSemaphore); PR_ASSERT(err == noErr); } - else #endif - { - GetCurrentProcess(&gApplicationProcess); - } } void TermIdleSemaphore() diff --git a/pr/src/md/mac/mdmac.c b/pr/src/md/mac/mdmac.c index cfa33b4f..6d65e578 100644 --- a/pr/src/md/mac/mdmac.c +++ b/pr/src/md/mac/mdmac.c @@ -70,6 +70,7 @@ unsigned char GarbageCollectorCacheFlusher(PRUint32 size); extern PRThread *gPrimaryThread; +extern ProcessSerialNumber gApplicationProcess; // in macthr.c //############################################################################## @@ -288,6 +289,8 @@ void _MD_EarlyInit() { Handle environmentVariables; + GetCurrentProcess(&gApplicationProcess); + INIT_CRITICAL_REGION(); InitIdleSemaphore(); |