зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
22a1bb0cb6
Коммит
c158ed074a
|
@ -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();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче