mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 870043 - Add a script-accessible statistics for various watchdog events. r=mrbkap
We need this even for testing wakeups, because we can't be certain that any given operation callback was necessarily triggered from the watchdog thread (since it's triggered from within the JS engine in various cases as well).
This commit is contained in:
parent
63f5620548
commit
93442ca1ad
@ -119,7 +119,7 @@ interface ScheduledGCCallback : nsISupports
|
||||
/**
|
||||
* interface of Components.utils
|
||||
*/
|
||||
[scriptable, uuid(fdd32d38-9341-4067-9000-d781075a60c9)]
|
||||
[scriptable, uuid(35d5b0e5-9b29-48de-9f79-d2534b497435)]
|
||||
interface nsIXPCComponents_Utils : nsISupports
|
||||
{
|
||||
|
||||
@ -426,6 +426,18 @@ interface nsIXPCComponents_Utils : nsISupports
|
||||
* names are supported.
|
||||
*/
|
||||
nsIClassInfo getDOMClassInfo(in AString aClassName);
|
||||
|
||||
/**
|
||||
* Retrieve the last time, in microseconds since epoch, that a given
|
||||
* watchdog-related event occured.
|
||||
*
|
||||
* Valid categories:
|
||||
* "RuntimeStateChange" - Runtime switching between active and inactive states
|
||||
* "WatchdogWakeup" - Watchdog waking up from sleeping
|
||||
* "WatchdogHibernateStart" - Watchdog begins hibernating
|
||||
* "WatchdogHibernateStop" - Watchdog stops hibernating
|
||||
*/
|
||||
PRTime getWatchdogTimestamp(in AString aCategory);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4541,6 +4541,24 @@ nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime *aOut)
|
||||
{
|
||||
WatchdogTimestampCategory category;
|
||||
if (aCategory.EqualsLiteral("RuntimeStateChange"))
|
||||
category = TimestampRuntimeStateChange;
|
||||
else if (aCategory.EqualsLiteral("WatchdogWakeup"))
|
||||
category = TimestampWatchdogWakeup;
|
||||
else if (aCategory.EqualsLiteral("WatchdogHibernateStart"))
|
||||
category = TimestampWatchdogHibernateStart;
|
||||
else if (aCategory.EqualsLiteral("WatchdogHibernateStop"))
|
||||
category = TimestampWatchdogHibernateStop;
|
||||
else
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
*aOut = XPCJSRuntime::Get()->GetWatchdogTimestamp(category);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
@ -995,11 +995,15 @@ class Watchdog
|
||||
class WatchdogManager : public nsIObserver
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
WatchdogManager(XPCJSRuntime *aRuntime) : mRuntime(aRuntime)
|
||||
, mRuntimeState(RUNTIME_INACTIVE)
|
||||
, mTimeAtLastRuntimeStateChange(PR_Now())
|
||||
{
|
||||
// All the timestamps start at zero except for runtime state change.
|
||||
PodArrayZero(mTimestamps);
|
||||
mTimestamps[TimestampRuntimeStateChange] = PR_Now();
|
||||
|
||||
// Enable the watchdog, if appropriate.
|
||||
RefreshWatchdog();
|
||||
|
||||
@ -1029,12 +1033,13 @@ class WatchdogManager : public nsIObserver
|
||||
RecordRuntimeActivity(bool active)
|
||||
{
|
||||
// The watchdog reads this state, so acquire the lock before writing it.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
Maybe<AutoLockWatchdog> lock;
|
||||
if (mWatchdog)
|
||||
lock.construct(mWatchdog);
|
||||
|
||||
// Write state.
|
||||
mTimeAtLastRuntimeStateChange = PR_Now();
|
||||
mTimestamps[TimestampRuntimeStateChange] = PR_Now();
|
||||
mRuntimeState = active ? RUNTIME_ACTIVE : RUNTIME_INACTIVE;
|
||||
|
||||
// The watchdog may be hibernating, waiting for the runtime to go
|
||||
@ -1045,7 +1050,26 @@ class WatchdogManager : public nsIObserver
|
||||
bool IsRuntimeActive() { return mRuntimeState == RUNTIME_ACTIVE; }
|
||||
PRTime TimeSinceLastRuntimeStateChange()
|
||||
{
|
||||
return PR_Now() - mTimeAtLastRuntimeStateChange;
|
||||
return PR_Now() - GetTimestamp(TimestampRuntimeStateChange);
|
||||
}
|
||||
|
||||
// Note - Because of the runtime activity timestamp, these are read and
|
||||
// written from both threads.
|
||||
void RecordTimestamp(WatchdogTimestampCategory aCategory)
|
||||
{
|
||||
// The watchdog thread always holds the lock when it runs.
|
||||
Maybe<AutoLockWatchdog> maybeLock;
|
||||
if (NS_IsMainThread() && mWatchdog)
|
||||
maybeLock.construct(mWatchdog);
|
||||
mTimestamps[aCategory] = PR_Now();
|
||||
}
|
||||
PRTime GetTimestamp(WatchdogTimestampCategory aCategory)
|
||||
{
|
||||
// The watchdog thread always holds the lock when it runs.
|
||||
Maybe<AutoLockWatchdog> maybeLock;
|
||||
if (NS_IsMainThread() && mWatchdog)
|
||||
maybeLock.construct(mWatchdog);
|
||||
return mTimestamps[aCategory];
|
||||
}
|
||||
|
||||
XPCJSRuntime* Runtime() { return mRuntime; }
|
||||
@ -1081,7 +1105,7 @@ class WatchdogManager : public nsIObserver
|
||||
nsAutoPtr<Watchdog> mWatchdog;
|
||||
|
||||
enum { RUNTIME_ACTIVE, RUNTIME_INACTIVE } mRuntimeState;
|
||||
PRTime mTimeAtLastRuntimeStateChange;
|
||||
PRTime mTimestamps[TimestampCount];
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(WatchdogManager, nsIObserver)
|
||||
@ -1116,9 +1140,14 @@ WatchdogMain(void *arg)
|
||||
{
|
||||
self->Sleep(PR_TicksPerSecond());
|
||||
} else {
|
||||
manager->RecordTimestamp(TimestampWatchdogHibernateStart);
|
||||
self->Hibernate();
|
||||
manager->RecordTimestamp(TimestampWatchdogHibernateStop);
|
||||
}
|
||||
|
||||
// Rise and shine.
|
||||
manager->RecordTimestamp(TimestampWatchdogWakeup);
|
||||
|
||||
// Don't trigger the operation callback if activity started less than one second ago.
|
||||
// The callback is only used for detecting long running scripts, and triggering the
|
||||
// callback from off the main thread can be expensive.
|
||||
@ -1133,6 +1162,12 @@ WatchdogMain(void *arg)
|
||||
self->Finished();
|
||||
}
|
||||
|
||||
PRTime
|
||||
XPCJSRuntime::GetWatchdogTimestamp(WatchdogTimestampCategory aCategory)
|
||||
{
|
||||
return mWatchdogManager->GetTimestamp(aCategory);
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
XPCJSRuntime::ActivityCallback(void *arg, JSBool active)
|
||||
|
@ -596,6 +596,16 @@ public:
|
||||
|
||||
class XPCJSContextStack;
|
||||
class WatchdogManager;
|
||||
|
||||
enum WatchdogTimestampCategory
|
||||
{
|
||||
TimestampRuntimeStateChange = 0,
|
||||
TimestampWatchdogWakeup,
|
||||
TimestampWatchdogHibernateStart,
|
||||
TimestampWatchdogHibernateStop,
|
||||
TimestampCount
|
||||
};
|
||||
|
||||
class XPCJSRuntime : public mozilla::CycleCollectedJSRuntime
|
||||
{
|
||||
public:
|
||||
@ -817,6 +827,9 @@ public:
|
||||
|
||||
JSObject* GetJunkScope();
|
||||
void DeleteJunkScope();
|
||||
|
||||
PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
|
||||
|
||||
private:
|
||||
XPCJSRuntime(); // no implementation
|
||||
XPCJSRuntime(nsXPConnect* aXPConnect);
|
||||
|
Loading…
Reference in New Issue
Block a user