Backed out changeset 693868d079cd (bug 836654)

This commit is contained in:
Ed Morley 2013-02-14 10:02:35 +00:00
Родитель 8d3e1b8cde
Коммит 96f0163d6e
3 изменённых файлов: 64 добавлений и 181 удалений

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

@ -546,7 +546,7 @@ pref("ui.showHideScrollbars", 1);
// background.
pref("dom.ipc.processPriorityManager.enabled", true);
pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
pref("dom.ipc.processPriorityManager.temporaryPriorityMS", 5000);
// Kernel parameters for how processes are killed on low-memory.
pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);

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

@ -83,15 +83,36 @@ GetPPMLog()
#define LOG(fmt, ...)
#endif
uint64_t
GetContentChildID()
/**
* Get the appropriate backround priority for this process.
*/
ProcessPriority
GetBackgroundPriority()
{
ContentChild* contentChild = ContentChild::GetSingleton();
if (!contentChild) {
return 0;
AudioChannelService* service = AudioChannelService::GetAudioChannelService();
if (service->ContentOrNormalChannelIsActive()) {
return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE;
}
return contentChild->GetID();
bool isHomescreen = false;
ContentChild* contentChild = ContentChild::GetSingleton();
if (contentChild) {
const InfallibleTArray<PBrowserChild*>& browsers =
contentChild->ManagedPBrowserChild();
for (uint32_t i = 0; i < browsers.Length(); i++) {
nsAutoString appType;
static_cast<TabChild*>(browsers[i])->GetAppType(appType);
if (appType.EqualsLiteral("homescreen")) {
isHomescreen = true;
break;
}
}
}
return isHomescreen ?
PROCESS_PRIORITY_BACKGROUND_HOMESCREEN :
PROCESS_PRIORITY_BACKGROUND;
}
/**
@ -137,7 +158,6 @@ class ProcessPriorityManager MOZ_FINAL
: public nsIObserver
, public nsIDOMEventListener
, public nsITimerCallback
, public WakeLockObserver
{
public:
ProcessPriorityManager();
@ -147,21 +167,20 @@ public:
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIOBSERVER
NS_DECL_NSIDOMEVENTLISTENER
void Notify(const WakeLockInformation& aWakeLockInfo);
ProcessPriority GetPriority() const { return mProcessPriority; }
/**
* This function doesn't do exactly what you might think; see the comment on
* ProcessPriorityManager.h::TemporarilyLockProcessPriority().
* If this process is not already in the foreground, move it into the
* foreground and set a timer to call ResetPriorityNow() in a few seconds.
*/
void TemporarilyLockProcessPriority();
void TemporarilySetIsForeground();
/**
* Recompute this process's priority and apply it, potentially after a brief
* delay.
*
* If the new priority is FOREGROUND*, it takes effect immediately.
* If the new priority is FOREGROUND, it takes effect immediately.
*
* If the new priority is a BACKGROUND* priority and this process's priority
* is currently a BACKGROUND* priority, the new priority takes effect
@ -181,30 +200,13 @@ public:
private:
void OnContentDocumentGlobalCreated(nsISupports* aOuterWindow);
/**
* Is this process a "critical" process that's holding the "CPU" or
* "high-priority" wake lock?
*/
bool IsCriticalProcessWithWakeLock();
/**
* If this process were in the foreground, what priority would it have?
*/
ProcessPriority GetForegroundPriority();
/**
* If this process were in the foreground, what priority would it have?
*/
ProcessPriority GetBackgroundPriority();
/**
* Compute whether this process is in the foreground and return the result.
*/
bool ComputeIsInForeground();
/**
* Set this process's priority to the appropriate FOREGROUND* priority
* immediately.
* Set this process's priority to FOREGROUND immediately.
*/
void SetIsForeground();
@ -222,12 +224,6 @@ private:
void
ScheduleResetPriority(const char* aTimeoutPref);
// Tracks whether this process holds the "cpu" lock.
bool mHoldsCPUWakeLock;
// Tracks whether this process holds the "high-priority" lock.
bool mHoldsHighPriorityWakeLock;
// mProcessPriority tracks the priority we've given this process in hal.
ProcessPriority mProcessPriority;
@ -240,20 +236,20 @@ private:
nsWeakPtr mMemoryMinimizerRunnable;
};
NS_IMPL_ISUPPORTS2(ProcessPriorityManager, nsIObserver, nsIDOMEventListener)
NS_IMPL_ISUPPORTS3(ProcessPriorityManager, nsIObserver,
nsIDOMEventListener, nsITimerCallback)
ProcessPriorityManager::ProcessPriorityManager()
: mHoldsCPUWakeLock(false)
, mHoldsHighPriorityWakeLock(false)
, mProcessPriority(ProcessPriority(-1))
: mProcessPriority(ProcessPriority(-1))
{
// When our parent process forked us, it may have set our process's priority
// to one of a few of the process priorities, depending on exactly why this
// process was created.
// When our parent process forked us, it set our priority either to
// FOREGROUND (if our parent launched this process to meet an immediate need)
// or one of the BACKGROUND priorities (if our parent launched this process
// to meet a future need).
//
// We don't know which priority we were given, so we set mProcessPriority to
// -1 so that the next time ResetPriorityNow is run, we'll definitely call
// into hal and set our priority.
// We don't know which situation we're in, so we set mProcessPriority to -1
// so that the next time ResetPriorityNow is run, we'll definitely call into
// hal and set our priority.
}
void
@ -273,20 +269,6 @@ ProcessPriorityManager::Init()
os->AddObserver(this, "inner-window-destroyed", /* ownsWeak = */ false);
os->AddObserver(this, "audio-channel-agent-changed", /* ownsWeak = */ false);
os->AddObserver(this, "process-priority:reset-now", /* ownsWeak = */ false);
RegisterWakeLockObserver(this);
// This process may already hold the CPU lock; for example, our parent may
// have acquired it on our behalf.
WakeLockInformation info1, info2;
GetWakeLockInfo(NS_LITERAL_STRING("cpu"), &info1);
mHoldsCPUWakeLock = info1.lockingProcesses().Contains(GetContentChildID());
GetWakeLockInfo(NS_LITERAL_STRING("high-priority"), &info2);
mHoldsHighPriorityWakeLock = info2.lockingProcesses().Contains(GetContentChildID());
LOG("Done starting up. mHoldsCPUWakeLock=%d, mHoldsHighPriorityWakeLock=%d",
mHoldsCPUWakeLock, mHoldsHighPriorityWakeLock);
}
NS_IMETHODIMP
@ -309,30 +291,6 @@ ProcessPriorityManager::Observe(
return NS_OK;
}
void
ProcessPriorityManager::Notify(const WakeLockInformation& aInfo)
{
bool* dest = nullptr;
if (aInfo.topic() == NS_LITERAL_STRING("cpu")) {
dest = &mHoldsCPUWakeLock;
} else if (aInfo.topic() == NS_LITERAL_STRING("high-priority")) {
dest = &mHoldsHighPriorityWakeLock;
}
if (dest) {
bool thisProcessLocks =
aInfo.lockingProcesses().Contains(GetContentChildID());
if (thisProcessLocks != *dest) {
*dest = thisProcessLocks;
LOG("Got wake lock changed event. "
"Now mHoldsCPUWakeLock=%d, mHoldsHighPriorityWakeLock=%d",
mHoldsCPUWakeLock, mHoldsHighPriorityWakeLock);
ResetPriority();
}
}
}
NS_IMETHODIMP
ProcessPriorityManager::HandleEvent(
nsIDOMEvent* aEvent)
@ -378,75 +336,9 @@ ProcessPriorityManager::OnContentDocumentGlobalCreated(
/* wantsUntrusted = */ false);
mWindows.AppendElement(weakWin);
ResetPriority();
}
bool
ProcessPriorityManager::IsCriticalProcessWithWakeLock()
{
if (!(mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock)) {
return false;
}
ContentChild* contentChild = ContentChild::GetSingleton();
if (!contentChild) {
return false;
}
const InfallibleTArray<PBrowserChild*>& browsers =
contentChild->ManagedPBrowserChild();
for (uint32_t i = 0; i < browsers.Length(); i++) {
nsAutoString appType;
static_cast<TabChild*>(browsers[i])->GetAppType(appType);
if (appType.EqualsLiteral("critical")) {
return true;
}
}
return false;
}
ProcessPriority
ProcessPriorityManager::GetForegroundPriority()
{
return IsCriticalProcessWithWakeLock() ? PROCESS_PRIORITY_FOREGROUND_HIGH :
PROCESS_PRIORITY_FOREGROUND;
}
/**
* Get the appropriate backround priority for this process.
*/
ProcessPriority
ProcessPriorityManager::GetBackgroundPriority()
{
AudioChannelService* service = AudioChannelService::GetAudioChannelService();
if (service->ContentOrNormalChannelIsActive()) {
return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE;
}
bool isHomescreen = false;
ContentChild* contentChild = ContentChild::GetSingleton();
if (contentChild) {
const InfallibleTArray<PBrowserChild*>& browsers =
contentChild->ManagedPBrowserChild();
for (uint32_t i = 0; i < browsers.Length(); i++) {
nsAutoString appType;
static_cast<TabChild*>(browsers[i])->GetAppType(appType);
if (appType.EqualsLiteral("homescreen")) {
isHomescreen = true;
break;
}
}
}
return isHomescreen ?
PROCESS_PRIORITY_BACKGROUND_HOMESCREEN :
PROCESS_PRIORITY_BACKGROUND;
}
void
ProcessPriorityManager::ResetPriority()
{
@ -474,12 +366,6 @@ ProcessPriorityManager::ResetPriorityNow()
bool
ProcessPriorityManager::ComputeIsInForeground()
{
// Critical processes holding the CPU/high-priority wake lock are always
// considered to be in the foreground.
if (IsCriticalProcessWithWakeLock()) {
return true;
}
// We could try to be clever and keep a running count of the number of active
// docshells, instead of iterating over mWindows every time one window's
// visibility state changes. But experience suggests that iterating over the
@ -504,7 +390,6 @@ ProcessPriorityManager::ComputeIsInForeground()
bool isActive = false;
docshell->GetIsActive(&isActive);
#ifdef DEBUG
nsAutoCString spec;
nsCOMPtr<nsIURI> uri = window->GetDocumentURI();
@ -527,8 +412,7 @@ ProcessPriorityManager::ComputeIsInForeground()
void
ProcessPriorityManager::SetIsForeground()
{
ProcessPriority foregroundPriority = GetForegroundPriority();
if (foregroundPriority == mProcessPriority) {
if (mProcessPriority == PROCESS_PRIORITY_FOREGROUND) {
return;
}
@ -539,7 +423,7 @@ ProcessPriorityManager::SetIsForeground()
runnable->Cancel();
}
mProcessPriority = foregroundPriority;
mProcessPriority = PROCESS_PRIORITY_FOREGROUND;
LOG("Setting priority to %s.", ProcessPriorityToString(mProcessPriority));
hal::SetProcessPriority(getpid(), PROCESS_PRIORITY_FOREGROUND);
}
@ -578,7 +462,7 @@ void
ProcessPriorityManager::ScheduleResetPriority(const char* aTimeoutPref)
{
if (mResetPriorityTimer) {
LOG("ScheduleResetPriority bailing; the timer is already running.");
// The timer is already running.
return;
}
@ -599,20 +483,20 @@ ProcessPriorityManager::Notify(nsITimer* aTimer)
}
void
ProcessPriorityManager::TemporarilyLockProcessPriority()
ProcessPriorityManager::TemporarilySetIsForeground()
{
LOG("TemporarilyLockProcessPriority");
LOG("TemporarilySetIsForeground");
SetIsForeground();
// Each call to TemporarilyLockProcessPriority gives us an additional
// temporaryPriorityMS at our current priority (unless we receive a
// process-priority:reset-now notification). So cancel our timer if it's
// running (which is due to a previous call to either
// TemporarilyLockProcessPriority() or ResetPriority()).
// Each call to TemporarilySetIsForeground guarantees us temporaryPriorityMS
// in the foreground (unless we receive a process-priority:reset-now
// notification). So cancel our timer if it's running (which is due to a
// previous call to either TemporarilySetIsForeground() or ResetPriority()).
if (mResetPriorityTimer) {
mResetPriorityTimer->Cancel();
mResetPriorityTimer = nullptr;
}
ScheduleResetPriority("temporaryPriorityLockMS");
ScheduleResetPriority("temporaryPriorityMS");
}
} // anonymous namespace
@ -660,12 +544,12 @@ CurrentProcessIsForeground()
}
void
TemporarilyLockProcessPriority()
TemporarilySetProcessPriorityToForeground()
{
if (sManager) {
sManager->TemporarilyLockProcessPriority();
sManager->TemporarilySetIsForeground();
} else {
LOG("TemporarilyLockProcessPriority called before "
LOG("TemporarilySetProcessPriorityToForeground called before "
"InitProcessPriorityManager. Bailing.");
}
}

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

@ -34,16 +34,15 @@ void InitProcessPriorityManager();
bool CurrentProcessIsForeground();
/**
* Calling this function prevents us from changing this process's priority
* for a few seconds, if that change in priority would not have taken effect
* immediately to begin with.
* If this process is in the background, temporarily boost its priority to the
* foreground. This priority boost will expire after a few seconds
* (dom.ipc.processPriorityManager.temporaryPriorityMS).
*
* In practice, this prevents foreground --> background transitions, but not
* background --> foreground transitions. It also does not prevent
* transitions from an unknown priority (as happens immediately after we're
* constructed) to a foreground priority.
* You might want to call this function when a process starts loading some
* things, but doesn't yet have a foreground window. The hope would be that by
* once the timer here expires, the process will have a foreground window.
*/
void TemporarilyLockProcessPriority();
void TemporarilySetProcessPriorityToForeground();
} // namespace ipc
} // namespace dom