summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfraser%netscape.com <devnull@localhost>2002-07-15 22:56:54 +0000
committersfraser%netscape.com <devnull@localhost>2002-07-15 22:56:54 +0000
commitbc14a71fa1e4dca6fdeed0dba5abc5898ea30d75 (patch)
tree09afa9ad32d5b4c5ffee1b5fd57a46a1fc5405f6
parentf4d7eb742429bf276f0086b3ff03f6c2aac1c1da (diff)
downloadnspr-hg-bc14a71fa1e4dca6fdeed0dba5abc5898ea30d75.tar.gz
Fixing bug 139802 on the branch. Avoid spending lots of time in WaitNextEvent when there are NSPR threads running. r=wtc, sdagley. a=chofmann
-rw-r--r--pr/src/md/mac/macthr.c30
-rw-r--r--pr/src/md/mac/mdmac.c3
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();