From 96f0163d6e3952a82a6ce124385be9dd18251cce Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Thu, 14 Feb 2013 10:02:35 +0000 Subject: [PATCH] Backed out changeset 693868d079cd (bug 836654) --- b2g/app/b2g.js | 2 +- dom/ipc/ProcessPriorityManager.cpp | 228 +++++++---------------------- dom/ipc/ProcessPriorityManager.h | 15 +- 3 files changed, 64 insertions(+), 181 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index aed15d06faba..954597000d09 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -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); diff --git a/dom/ipc/ProcessPriorityManager.cpp b/dom/ipc/ProcessPriorityManager.cpp index 424cbc603dd1..9284e42ef3fa 100644 --- a/dom/ipc/ProcessPriorityManager.cpp +++ b/dom/ipc/ProcessPriorityManager.cpp @@ -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& browsers = + contentChild->ManagedPBrowserChild(); + for (uint32_t i = 0; i < browsers.Length(); i++) { + nsAutoString appType; + static_cast(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& browsers = - contentChild->ManagedPBrowserChild(); - for (uint32_t i = 0; i < browsers.Length(); i++) { - nsAutoString appType; - static_cast(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& browsers = - contentChild->ManagedPBrowserChild(); - for (uint32_t i = 0; i < browsers.Length(); i++) { - nsAutoString appType; - static_cast(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 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."); } } diff --git a/dom/ipc/ProcessPriorityManager.h b/dom/ipc/ProcessPriorityManager.h index fec113f8fb71..9b5ecbc2ddc5 100644 --- a/dom/ipc/ProcessPriorityManager.h +++ b/dom/ipc/ProcessPriorityManager.h @@ -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