Bug 568730 - Allow customizing the sleep duration in XPCJSRuntime::WatchdogMain. r=igor/jst/gal

This commit is contained in:
Alon Zakai 2010-08-09 16:39:28 -07:00
parent 71cf6e222a
commit 8ba541a087
4 changed files with 59 additions and 4 deletions

View File

@ -805,6 +805,9 @@ JS_BeginRequest(JSContext *cx)
cx->outstandingRequests++;
cx->thread->requestContext = cx;
rt->requestCount++;
if (rt->requestCount == 1)
rt->activityCallback(rt->activityCallbackArg, true);
}
#endif
}
@ -853,8 +856,10 @@ StopRequest(JSContext *cx)
/* Give the GC a chance to run if this was the last request running. */
JS_ASSERT(rt->requestCount > 0);
rt->requestCount--;
if (rt->requestCount == 0)
if (rt->requestCount == 0) {
JS_NOTIFY_REQUEST_DONE(rt);
rt->activityCallback(rt->activityCallbackArg, false);
}
}
}
#endif

View File

@ -1218,6 +1218,9 @@ struct JSCompartment {
void sweep(JSContext *cx);
};
typedef void
(* JSActivityCallback)(void *arg, JSBool active);
struct JSRuntime {
/* Default compartment. */
JSCompartment *defaultCompartment;
@ -1234,6 +1237,20 @@ struct JSRuntime {
/* Compartment create/destroy callback. */
JSCompartmentCallback compartmentCallback;
/*
* Sets a callback that is run whenever the runtime goes idle - the
* last active request ceases - and begins activity - when it was
* idle and a request begins. Note: The callback is called under the
* GC lock.
*/
void setActivityCallback(JSActivityCallback cb, void *arg) {
activityCallback = cb;
activityCallbackArg = arg;
}
JSActivityCallback activityCallback;
void *activityCallbackArg;
/*
* Shape regenerated whenever a prototype implicated by an "add property"
* property cache fill and induced trace guard has a readonly property or a

View File

@ -803,14 +803,22 @@ XPCJSRuntime::WatchdogMain(void *arg)
// Lock lasts until we return
AutoLockJSGC lock(self->mJSRuntime);
PRIntervalTime sleepInterval;
while (self->mWatchdogThread)
{
// Sleep only 1 second if recently (or currently) active; otherwise, hibernate
if (self->mLastActiveTime == -1 || PR_Now() - self->mLastActiveTime <= 2*PR_USEC_PER_SEC)
sleepInterval = PR_TicksPerSecond();
else
{
sleepInterval = PR_INTERVAL_NO_TIMEOUT;
self->mWatchdogHibernating = PR_TRUE;
}
#ifdef DEBUG
PRStatus status =
#endif
PR_WaitCondVar(self->mWatchdogWakeup, PR_TicksPerSecond());
PR_WaitCondVar(self->mWatchdogWakeup, sleepInterval);
JS_ASSERT(status == PR_SUCCESS);
JSContext* cx = nsnull;
while((cx = js_NextActiveContext(self->mJSRuntime, cx)))
{
@ -822,6 +830,23 @@ XPCJSRuntime::WatchdogMain(void *arg)
PR_NotifyCondVar(self->mWatchdogWakeup);
}
//static
void
XPCJSRuntime::ActivityCallback(void *arg, PRBool active)
{
XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg);
if (active) {
self->mLastActiveTime = -1;
if (self->mWatchdogHibernating)
{
self->mWatchdogHibernating = PR_FALSE;
PR_NotifyCondVar(self->mWatchdogWakeup);
}
} else {
self->mLastActiveTime = PR_Now();
}
}
/***************************************************************************/
@ -1108,7 +1133,9 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
mWrappedJSRoots(nsnull),
mObjectHolderRoots(nsnull),
mWatchdogWakeup(nsnull),
mWatchdogThread(nsnull)
mWatchdogThread(nsnull),
mWatchdogHibernating(PR_FALSE),
mLastActiveTime(-1)
{
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
DEBUG_WrappedNativeHashtable =
@ -1138,6 +1165,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
JS_SetExtraGCRoots(mJSRuntime, TraceJS, this);
mWatchdogWakeup = JS_NEW_CONDVAR(mJSRuntime->gcLock);
mJSRuntime->setActivityCallback(ActivityCallback, this);
mJSRuntime->setCustomGCChunkAllocator(&gXPCJSChunkAllocator);
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPConnectJSRuntimeGCChunks));

View File

@ -720,6 +720,8 @@ public:
void AddGCCallback(JSGCCallback cb);
void RemoveGCCallback(JSGCCallback cb);
static void ActivityCallback(void *arg, PRBool active);
private:
XPCJSRuntime(); // no implementation
XPCJSRuntime(nsXPConnect* aXPConnect);
@ -758,6 +760,8 @@ private:
PRCondVar *mWatchdogWakeup;
PRThread *mWatchdogThread;
nsTArray<JSGCCallback> extraGCCallbacks;
PRBool mWatchdogHibernating;
PRTime mLastActiveTime; // -1 if active NOW
};
/***************************************************************************/