Backed out changeset 693868d079cd (bug 836654)
authorEd Morley <emorley@mozilla.com>
Thu, 14 Feb 2013 10:02:35 +0000
changeset 131752 a93b93dc2d4b69fc0eaa3b61b541abea72e90d1a
parent 131751 8443f568ecde7c031e2abd229710f6d838c6be6c
child 131753 01affac8c8fb762ee4e4fb759a300c7603fdba17
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs836654
milestone21.0a1
backs out693868d079cd33429780dc3466248dae2c238cfc
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 693868d079cd (bug 836654)
b2g/app/b2g.js
dom/ipc/ProcessPriorityManager.cpp
dom/ipc/ProcessPriorityManager.h
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -541,17 +541,17 @@ pref("dom.workers.mem.gc_allocation_thre
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // 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);
 pref("hal.processPriorityManager.gonk.masterOomScoreAdjust", 0);
 pref("hal.processPriorityManager.gonk.masterKillUnderMB", 1);
 pref("hal.processPriorityManager.gonk.foregroundHighOomScoreAdjust", 67);
 pref("hal.processPriorityManager.gonk.foregroundHighKillUnderMB", 3);
 pref("hal.processPriorityManager.gonk.foregroundOomScoreAdjust", 134);
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -78,25 +78,46 @@ GetPPMLog()
 }
 #define LOG(fmt, ...) \
   PR_LOG(GetPPMLog(), PR_LOG_DEBUG,                                     \
          ("[%d] ProcessPriorityManager - " fmt, getpid(), ##__VA_ARGS__))
 #else
 #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;
 }
 
 /**
  * Determine if the priority is a backround priority.
  */
 bool
 IsBackgroundPriority(ProcessPriority aPriority)
 {
@@ -132,41 +153,39 @@ IsBackgroundPriority(ProcessPriority aPr
  * the previous app into the background.  This ensures that there's only one
  * foreground app at a time, thus ensuring that we kill the right process if we
  * come under memory pressure.
  */
 class ProcessPriorityManager MOZ_FINAL
   : public nsIObserver
   , public nsIDOMEventListener
   , public nsITimerCallback
-  , public WakeLockObserver
 {
 public:
   ProcessPriorityManager();
   void Init();
 
   NS_DECL_ISUPPORTS
   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
    * immediately.
    *
    * But if the new priority is a BACKGROUND* priority and this process is not
    * currently in the background, we schedule a timer and run
    * ResetPriorityNow() after a short period of time.
@@ -177,39 +196,22 @@ public:
    * Recompute this process's priority and apply it immediately.
    */
   void ResetPriorityNow();
 
 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();
 
   /**
    * Set this process's priority to the appropriate BACKGROUND* priority
    * immediately.
    */
   void SetIsBackgroundNow();
@@ -217,48 +219,42 @@ private:
   /**
    * If mResetPriorityTimer is null (i.e., not running), create a timer and set
    * it to invoke ResetPriorityNow() after
    * dom.ipc.processPriorityManager.aTimeoutPref ms.
    */
   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;
 
   nsTArray<nsWeakPtr> mWindows;
 
   // When this timer expires, we set mResetPriorityTimer to null and run
   // ResetPriorityNow().
   nsCOMPtr<nsITimer> mResetPriorityTimer;
 
   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
 ProcessPriorityManager::Init()
 {
   LOG("Starting up.");
 
   // We can't do this in the constructor because we need to hold a strong ref
@@ -268,30 +264,16 @@ ProcessPriorityManager::Init()
   // notion of "is-foreground" is tied to /docshell/ activity.  We do this
   // because docshells don't fire an event when their visibility changes, but
   // windows do.
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   os->AddObserver(this, "content-document-global-created", /* ownsWeak = */ false);
   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
 ProcessPriorityManager::Observe(
   nsISupports* aSubject,
   const char* aTopic,
   const PRUnichar* aData)
 {
@@ -304,40 +286,16 @@ ProcessPriorityManager::Observe(
     LOG("Got process-priority:reset-now notification.");
     ResetPriorityNow();
   } else {
     MOZ_ASSERT(false);
   }
   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)
 {
   LOG("Got visibilitychange.");
   ResetPriority();
   return NS_OK;
 }
@@ -373,85 +331,19 @@ ProcessPriorityManager::OnContentDocumen
   }
 
   target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
                                  this,
                                  /* useCapture = */ false,
                                  /* 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()
 {
   if (ComputeIsInForeground()) {
     SetIsForeground();
   } else if (IsBackgroundPriority(mProcessPriority)) {
     // If we're already in the background, recompute our background priority
     // and set it immediately.
@@ -469,22 +361,16 @@ ProcessPriorityManager::ResetPriorityNow
   } else {
     SetIsBackgroundNow();
   }
 }
 
 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
   // windows is prone to fewer errors (and one mistake doesn't mess you up for
   // the entire session).  Moreover, mWindows should be a very short list,
   // since it contains only top-level content windows.
 
   bool allHidden = true;
@@ -499,17 +385,16 @@ ProcessPriorityManager::ComputeIsInForeg
     nsCOMPtr<nsIDocShell> docshell = do_GetInterface(window);
     if (!docshell) {
       continue;
     }
 
     bool isActive = false;
     docshell->GetIsActive(&isActive);
 
-
 #ifdef DEBUG
     nsAutoCString spec;
     nsCOMPtr<nsIURI> uri = window->GetDocumentURI();
     if (uri) {
       uri->GetSpec(spec);
     }
     LOG("Docshell at %s has visibility %d.", spec.get(), isActive);
 #endif
@@ -522,29 +407,28 @@ ProcessPriorityManager::ComputeIsInForeg
   }
 
   return !allHidden;
 }
 
 void
 ProcessPriorityManager::SetIsForeground()
 {
-  ProcessPriority foregroundPriority = GetForegroundPriority();
-  if (foregroundPriority == mProcessPriority) {
+  if (mProcessPriority == PROCESS_PRIORITY_FOREGROUND) {
     return;
   }
 
   // Cancel the memory minimization procedure we might have started.
   nsCOMPtr<nsICancelableRunnable> runnable =
     do_QueryReferent(mMemoryMinimizerRunnable);
   if (runnable) {
     runnable->Cancel();
   }
 
-  mProcessPriority = foregroundPriority;
+  mProcessPriority = PROCESS_PRIORITY_FOREGROUND;
   LOG("Setting priority to %s.", ProcessPriorityToString(mProcessPriority));
   hal::SetProcessPriority(getpid(), PROCESS_PRIORITY_FOREGROUND);
 }
 
 void
 ProcessPriorityManager::SetIsBackgroundNow()
 {
   ProcessPriority backgroundPriority = GetBackgroundPriority();
@@ -573,17 +457,17 @@ ProcessPriorityManager::SetIsBackgroundN
     mMemoryMinimizerRunnable = do_GetWeakReference(runnable);
   }
 }
 
 void
 ProcessPriorityManager::ScheduleResetPriority(const char* aTimeoutPref)
 {
   if (mResetPriorityTimer) {
-    LOG("ScheduleResetPriority bailing; the timer is already running.");
+    // The timer is already running.
     return;
   }
 
   uint32_t timeout = Preferences::GetUint(
     nsPrintfCString("dom.ipc.processPriorityManager.%s", aTimeoutPref).get());
   LOG("Scheduling reset timer to fire in %dms.", timeout);
   mResetPriorityTimer = do_CreateInstance("@mozilla.org/timer;1");
   mResetPriorityTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
@@ -594,30 +478,30 @@ ProcessPriorityManager::Notify(nsITimer*
 {
   LOG("Reset priority timer callback; about to ResetPriorityNow.");
   ResetPriorityNow();
   mResetPriorityTimer = nullptr;
   return NS_OK;
 }
 
 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
 
 void
 InitProcessPriorityManager()
 {
   if (sInitialized) {
@@ -655,21 +539,21 @@ CurrentProcessIsForeground()
   if (!sManager) {
     return true;
   }
 
   return sManager->GetPriority() >= PROCESS_PRIORITY_FOREGROUND;
 }
 
 void
-TemporarilyLockProcessPriority()
+TemporarilySetProcessPriorityToForeground()
 {
   if (sManager) {
-    sManager->TemporarilyLockProcessPriority();
+    sManager->TemporarilySetIsForeground();
   } else {
-    LOG("TemporarilyLockProcessPriority called before "
+    LOG("TemporarilySetProcessPriorityToForeground called before "
         "InitProcessPriorityManager.  Bailing.");
   }
 }
 
 } // namespace ipc
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ProcessPriorityManager.h
+++ b/dom/ipc/ProcessPriorityManager.h
@@ -29,24 +29,23 @@ void InitProcessPriorityManager();
 /**
  * True iff the current process has foreground or higher priority as
  * computed by DOM visibility.  The returned answer may not match the
  * actual OS process priority, for short intervals.
  */
 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
 } // namespace mozilla
 
 #endif