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

This commit is contained in:
sfraser%netscape.com 2002-07-10 01:14:23 +00:00
Родитель 22a1bb0cb6
Коммит c158ed074a
2 изменённых файлов: 26 добавлений и 7 удалений

Просмотреть файл

@ -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()

Просмотреть файл

@ -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();