Bug 1368029 - Remove LRU priority support from ProcessPriorityManager, r=gsvelto
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 26 May 2017 17:50:17 +0200
changeset 360875 cb62a593770c8e7d02ae8344c018abe79a747406
parent 360874 d40d37c7b0c11646fe6f329138eaf61468cf3426
child 360876 4241cfd09e61d60f47bc9292879a22a3f058e14f
push id31903
push userryanvm@gmail.com
push dateFri, 26 May 2017 19:44:10 +0000
treeherdermozilla-central@bce03a8eac30 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgsvelto
bugs1368029
milestone55.0a1
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
Bug 1368029 - Remove LRU priority support from ProcessPriorityManager, r=gsvelto
dom/browser-element/mochitest/browserElementTestHelpers.js
dom/ipc/ProcessPriorityManager.cpp
hal/Hal.cpp
hal/Hal.h
hal/fallback/FallbackProcessPriority.cpp
hal/sandbox/SandboxHal.cpp
--- a/dom/browser-element/mochitest/browserElementTestHelpers.js
+++ b/dom/browser-element/mochitest/browserElementTestHelpers.js
@@ -45,18 +45,16 @@ const browserElementTestHelpers = {
     if (this._testReadyLockCount == 0 && !this._firedTestReady) {
       this._firedTestReady = true;
       dispatchEvent(new Event("testready"));
     }
   },
 
   enableProcessPriorityManager: function() {
     this._setPrefs(
-      ['dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels', 2],
-      ['dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels', 2],
       ['dom.ipc.processPriorityManager.testMode', true],
       ['dom.ipc.processPriorityManager.enabled', true]
     );
   },
 
   setClipboardPlainTextOnlyPref: function(value) {
     this._setPref('clipboard.plainTextOnly', value);
   },
@@ -192,56 +190,16 @@ function expectPriorityChange(childID, e
         } else {
           reject();
         }
       }
     );
   });
 }
 
-// Returns a promise which is resolved or rejected the next time the
-// process childID changes its priority.  We resolve if the expectedPriority
-// matches the priority and the LRU parameter matches expectedLRU and we
-// reject otherwise.
-
-function expectPriorityWithLRUSet(childID, expectedPriority, expectedLRU) {
-  return new Promise(function(resolve, reject) {
-    var observed = false;
-    browserElementTestHelpers.addProcessPriorityObserver(
-      'process-priority-with-LRU-set',
-      function(subject, topic, data) {
-        if (observed) {
-          return;
-        }
-
-        var [id, priority, lru] = data.split(":");
-        if (id != childID) {
-          return;
-        }
-
-        // Make sure we run the is() calls in this observer only once,
-        // otherwise we'll expect /every/ priority/LRU change to match
-        // expectedPriority/expectedLRU.
-        observed = true;
-
-        is(lru, expectedLRU,
-           'Expected LRU ' + lru +
-           ' of childID ' + childID +
-           ' to change to ' + expectedLRU);
-
-        if ((priority == expectedPriority) && (lru == expectedLRU)) {
-          resolve();
-        } else {
-          reject();
-        }
-      }
-    );
-  });
-}
-
 // Returns a promise which is resolved the first time the given iframe fires
 // the mozbrowser##eventName event.
 function expectMozbrowserEvent(iframe, eventName) {
   return new Promise(function(resolve, reject) {
     iframe.addEventListener('mozbrowser' + eventName, function handler(e) {
       iframe.removeEventListener('mozbrowser' + eventName, handler);
       resolve(e);
     });
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -87,50 +87,16 @@ using namespace mozilla::hal;
             NameWithComma().get(), \
             static_cast<uint64_t>(ChildID()), Pid(), ##__VA_ARGS__))
 #endif
 
 namespace {
 
 class ParticularProcessPriorityManager;
 
-class ProcessLRUPool final
-{
-public:
-  /**
-   * Creates a new process LRU pool for the specified priority.
-   */
-  explicit ProcessLRUPool(ProcessPriority aPriority);
-
-  /**
-   * Used to remove a particular process priority manager from the LRU pool
-   * when the associated ContentParent is destroyed or its priority changes.
-   */
-  void Remove(ParticularProcessPriorityManager* aParticularManager);
-
-  /**
-   * Used to add a particular process priority manager into the LRU pool when
-   * the associated ContentParent's priority changes.
-   */
-  void Add(ParticularProcessPriorityManager* aParticularManager);
-
-private:
-  ProcessPriority mPriority;
-  uint32_t mLRUPoolLevels;
-  nsTArray<ParticularProcessPriorityManager*> mLRUPool;
-
-  uint32_t CalculateLRULevel(uint32_t aLRUPoolIndex);
-
-  void AdjustLRUValues(
-    nsTArray<ParticularProcessPriorityManager*>::index_type aStart,
-    bool removed);
-
-  DISALLOW_EVIL_CONSTRUCTORS(ProcessLRUPool);
-};
-
 /**
  * This singleton class does the work to implement the process priority manager
  * in the main process.  This class may not be used in child processes.  (You
  * can call StaticInit, but it won't do anything, and GetSingleton() will
  * return null.)
  *
  * ProcessPriorityManager::CurrentProcessIsForeground() and
  * ProcessPriorityManager::AnyProcessHasHighPriority() which can be called in
@@ -155,18 +121,17 @@ public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   /**
    * This function implements ProcessPriorityManager::SetProcessPriority.
    */
   void SetProcessPriority(ContentParent* aContentParent,
-                          ProcessPriority aPriority,
-                          uint32_t aLRU = 0);
+                          ProcessPriority aPriority);
 
   /**
    * If a magic testing-only pref is set, notify the observer service on the
    * given topic with the given data.  This is used for testing
    */
   void FireTestOnlyObserverNotification(const char* aTopic,
                                         const nsACString& aData = EmptyCString());
 
@@ -233,22 +198,16 @@ private:
   nsDataHashtable<nsUint64HashKey, RefPtr<ParticularProcessPriorityManager> >
     mParticularManagers;
 
   /** True if the main process is holding a high-priority wakelock */
   bool mHighPriority;
 
   /** Contains the PIDs of child processes holding high-priority wakelocks */
   nsTHashtable<nsUint64HashKey> mHighPriorityChildIDs;
-
-  /** Contains a pseudo-LRU list of background processes */
-  ProcessLRUPool mBackgroundLRUPool;
-
-  /** Contains a pseudo-LRU list of background-perceivable processes */
-  ProcessLRUPool mBackgroundPerceivableLRUPool;
 };
 
 /**
  * This singleton class implements the parts of the process priority manager
  * that are available from all processes.
  */
 class ProcessPriorityManagerChild final
   : public nsIObserver
@@ -326,17 +285,17 @@ public:
   enum TimeoutPref {
     BACKGROUND_PERCEIVABLE_GRACE_PERIOD,
     BACKGROUND_GRACE_PERIOD,
   };
 
   void ScheduleResetPriority(TimeoutPref aTimeoutPref);
   void ResetPriority();
   void ResetPriorityNow();
-  void SetPriorityNow(ProcessPriority aPriority, uint32_t aLRU = 0);
+  void SetPriorityNow(ProcessPriority aPriority);
   void Freeze();
   void Unfreeze();
 
   void ShutDown();
 
 private:
   static uint32_t sBackgroundPerceivableGracePeriodMS;
   static uint32_t sBackgroundGracePeriodMS;
@@ -347,17 +306,16 @@ private:
 
   void FireTestOnlyObserverNotification(
     const char* aTopic,
     const char* aData = nullptr);
 
   ContentParent* mContentParent;
   uint64_t mChildID;
   ProcessPriority mPriority;
-  uint32_t mLRU;
   bool mHoldsCPUWakeLock;
   bool mHoldsHighPriorityWakeLock;
   bool mIsActivityOpener;
   bool mFrozen;
 
   /**
    * Used to implement NameWithComma().
    */
@@ -456,19 +414,17 @@ ProcessPriorityManagerImpl::GetSingleton
   if (!sSingleton) {
     StaticInit();
   }
 
   return sSingleton;
 }
 
 ProcessPriorityManagerImpl::ProcessPriorityManagerImpl()
-    : mHighPriority(false)
-    , mBackgroundLRUPool(PROCESS_PRIORITY_BACKGROUND)
-    , mBackgroundPerceivableLRUPool(PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE)
+  : mHighPriority(false)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   RegisterWakeLockObserver(this);
 }
 
 ProcessPriorityManagerImpl::~ProcessPriorityManagerImpl()
 {
   ShutDown();
@@ -534,24 +490,23 @@ ProcessPriorityManagerImpl::GetParticula
       nsPrintfCString("%" PRIu64, cpId));
   }
 
   return pppm.forget();
 }
 
 void
 ProcessPriorityManagerImpl::SetProcessPriority(ContentParent* aContentParent,
-                                               ProcessPriority aPriority,
-                                               uint32_t aLRU)
+                                               ProcessPriority aPriority)
 {
   MOZ_ASSERT(aContentParent);
   RefPtr<ParticularProcessPriorityManager> pppm =
     GetParticularProcessPriorityManager(aContentParent);
   if (pppm) {
-    pppm->SetPriorityNow(aPriority, aLRU);
+    pppm->SetPriorityNow(aPriority);
   }
 }
 
 void
 ProcessPriorityManagerImpl::ObserveContentParentCreated(
   nsISupports* aContentParent)
 {
   // Do nothing; it's sufficient to get the PPPM.  But assign to nsRefPtr so we
@@ -569,20 +524,16 @@ ProcessPriorityManagerImpl::ObserveConte
 
   uint64_t childID = CONTENT_PROCESS_ID_UNKNOWN;
   props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), &childID);
   NS_ENSURE_TRUE_VOID(childID != CONTENT_PROCESS_ID_UNKNOWN);
 
   RefPtr<ParticularProcessPriorityManager> pppm;
   mParticularManagers.Get(childID, &pppm);
   if (pppm) {
-    // Unconditionally remove the manager from the pools
-    mBackgroundLRUPool.Remove(pppm);
-    mBackgroundPerceivableLRUPool.Remove(pppm);
-
     pppm->ShutDown();
 
     mParticularManagers.Remove(childID);
 
     mHighPriorityChildIDs.RemoveEntry(childID);
   }
 }
 
@@ -610,32 +561,16 @@ ProcessPriorityManagerImpl::ChildProcess
 
 void
 ProcessPriorityManagerImpl::NotifyProcessPriorityChanged(
   ParticularProcessPriorityManager* aParticularManager,
   ProcessPriority aOldPriority)
 {
   ProcessPriority newPriority = aParticularManager->CurrentPriority();
 
-  if (newPriority == PROCESS_PRIORITY_BACKGROUND &&
-      aOldPriority != PROCESS_PRIORITY_BACKGROUND) {
-    mBackgroundLRUPool.Add(aParticularManager);
-  } else if (newPriority != PROCESS_PRIORITY_BACKGROUND &&
-      aOldPriority == PROCESS_PRIORITY_BACKGROUND) {
-    mBackgroundLRUPool.Remove(aParticularManager);
-  }
-
-  if (newPriority == PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE &&
-      aOldPriority != PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE) {
-    mBackgroundPerceivableLRUPool.Add(aParticularManager);
-  } else if (newPriority != PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE &&
-      aOldPriority == PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE) {
-    mBackgroundPerceivableLRUPool.Remove(aParticularManager);
-  }
-
   if (newPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH &&
     aOldPriority < PROCESS_PRIORITY_FOREGROUND_HIGH) {
     mHighPriorityChildIDs.PutEntry(aParticularManager->ChildID());
   } else if (newPriority < PROCESS_PRIORITY_FOREGROUND_HIGH &&
     aOldPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH) {
     mHighPriorityChildIDs.RemoveEntry(aParticularManager->ChildID());
   }
 }
@@ -663,17 +598,16 @@ NS_IMPL_ISUPPORTS(ParticularProcessPrior
                   nsITimerCallback,
                   nsISupportsWeakReference);
 
 ParticularProcessPriorityManager::ParticularProcessPriorityManager(
   ContentParent* aContentParent, bool aFrozen)
   : mContentParent(aContentParent)
   , mChildID(aContentParent->ChildID())
   , mPriority(PROCESS_PRIORITY_UNKNOWN)
-  , mLRU(0)
   , mHoldsCPUWakeLock(false)
   , mHoldsHighPriorityWakeLock(false)
   , mIsActivityOpener(false)
   , mFrozen(aFrozen)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   LOGP("Creating ParticularProcessPriorityManager.");
 }
@@ -1026,40 +960,32 @@ ParticularProcessPriorityManager::Comput
     return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE;
   }
 
   return mIsActivityOpener ? PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE
                            : PROCESS_PRIORITY_BACKGROUND;
 }
 
 void
-ParticularProcessPriorityManager::SetPriorityNow(ProcessPriority aPriority,
-                                                 uint32_t aLRU)
+ParticularProcessPriorityManager::SetPriorityNow(ProcessPriority aPriority)
 {
   if (aPriority == PROCESS_PRIORITY_UNKNOWN) {
     MOZ_ASSERT(false);
     return;
   }
 
   if (!ProcessPriorityManagerImpl::PrefsEnabled() ||
       !mContentParent ||
       mFrozen ||
-      ((mPriority == aPriority) && (mLRU == aLRU))) {
+      mPriority == aPriority) {
     return;
   }
 
-  if ((mPriority == aPriority) && (mLRU != aLRU)) {
-    mLRU = aLRU;
-    hal::SetProcessPriority(Pid(), mPriority, aLRU);
-
-    nsPrintfCString processPriorityWithLRU("%s:%d",
-      ProcessPriorityToString(mPriority), aLRU);
-
-    FireTestOnlyObserverNotification("process-priority-with-LRU-set",
-      processPriorityWithLRU.get());
+  if (mPriority == aPriority) {
+    hal::SetProcessPriority(Pid(), mPriority);
     return;
   }
 
   LOGP("Changing priority from %s to %s.",
        ProcessPriorityToString(mPriority),
        ProcessPriorityToString(aPriority));
 
   ProcessPriority oldPriority = mPriority;
@@ -1237,122 +1163,16 @@ ProcessPriorityManagerChild::CurrentProc
 
 bool
 ProcessPriorityManagerChild::CurrentProcessIsHighPriority()
 {
   return mCachedPriority == PROCESS_PRIORITY_UNKNOWN ||
          mCachedPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH;
 }
 
-ProcessLRUPool::ProcessLRUPool(ProcessPriority aPriority)
-  : mPriority(aPriority)
-  , mLRUPoolLevels(1)
-{
-  // We set mLRUPoolLevels according to our pref.
-  // This value is used to set background process LRU pool
-  const char* str = ProcessPriorityToString(aPriority);
-  nsPrintfCString pref("dom.ipc.processPriorityManager.%s.LRUPoolLevels", str);
-
-  Preferences::GetUint(pref.get(), &mLRUPoolLevels);
-
-  // GonkHal defines OOM_ADJUST_MAX is 15 and b2g.js defines
-  // PROCESS_PRIORITY_BACKGROUND's oom_score_adj is 667 and oom_adj is 10.
-  // This means we can only have at most (15 -10 + 1) = 6 background LRU levels.
-  // Similarly we can have at most 4 background perceivable LRU levels. We
-  // should really be getting rid of oom_adj and just rely on oom_score_adj
-  // only which would lift this constraint.
-  MOZ_ASSERT(aPriority != PROCESS_PRIORITY_BACKGROUND || mLRUPoolLevels <= 6);
-  MOZ_ASSERT(aPriority != PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE ||
-             mLRUPoolLevels <= 4);
-
-  // LRU pool size = 2 ^ (number of background LRU pool levels) - 1
-  uint32_t LRUPoolSize = (1 << mLRUPoolLevels) - 1;
-
-  LOG("Making %s LRU pool with size(%d)", str, LRUPoolSize);
-}
-
-uint32_t
-ProcessLRUPool::CalculateLRULevel(uint32_t aLRU)
-{
-  // This is used to compute the LRU adjustment for the specified LRU position.
-  // We use power-of-two groups with increasing adjustments that look like the
-  // following:
-
-  // Priority  : LRU0, LRU1
-  // Priority+1: LRU2, LRU3
-  // Priority+2: LRU4, LRU5, LRU6, LRU7
-  // Priority+3: LRU8, LRU9, LRU10, LRU11, LRU12, LRU12, LRU13, LRU14, LRU15
-  // ...
-  // Priority+L-1: 2^(number of LRU pool levels - 1)
-  // (End of buffer)
-
-  int exp;
-  Unused << frexp(static_cast<double>(aLRU), &exp);
-  uint32_t level = std::max(exp - 1, 0);
-
-  return std::min(mLRUPoolLevels - 1, level);
-}
-
-void
-ProcessLRUPool::Remove(ParticularProcessPriorityManager* aParticularManager)
-{
-  nsTArray<ParticularProcessPriorityManager*>::index_type index =
-    mLRUPool.IndexOf(aParticularManager);
-
-  if (index == nsTArray<ParticularProcessPriorityManager*>::NoIndex) {
-    return;
-  }
-
-  mLRUPool.RemoveElementAt(index);
-  AdjustLRUValues(index, /* removed */ true);
-
-  LOG("Remove ChildID(%" PRIu64 ") from %s LRU pool",
-      static_cast<uint64_t>(aParticularManager->ChildID()),
-      ProcessPriorityToString(mPriority));
-}
-
-/*
- * Adjust the LRU values of all the processes in an LRU pool. When true the
- * `removed` parameter indicates that the processes were shifted left because
- * an element was removed; otherwise it means the elements were shifted right
- * as an element was added.
- */
-void
-ProcessLRUPool::AdjustLRUValues(
-  nsTArray<ParticularProcessPriorityManager*>::index_type aStart,
-  bool removed)
-{
-  uint32_t adj = (removed ? 2 : 1);
-
-  for (nsTArray<ParticularProcessPriorityManager*>::index_type i = aStart;
-       i < mLRUPool.Length();
-       i++) {
-    /* Check whether i is a power of two.  If so, then it crossed a LRU group
-     * boundary and we need to assign its new process priority LRU. Note that
-     * depending on the direction and the bias this test will pick different
-     * elements. */
-    if (((i + adj) & (i + adj - 1)) == 0) {
-      mLRUPool[i]->SetPriorityNow(mPriority, CalculateLRULevel(i + 1));
-    }
-  }
-}
-
-void
-ProcessLRUPool::Add(ParticularProcessPriorityManager* aParticularManager)
-{
-  // Shift the list in the pool, so we have room at index 0 for the newly added
-  // manager
-  mLRUPool.InsertElementAt(0, aParticularManager);
-  AdjustLRUValues(1, /* removed */ false);
-
-  LOG("Add ChildID(%" PRIu64 ") into %s LRU pool",
-      static_cast<uint64_t>(aParticularManager->ChildID()),
-      ProcessPriorityToString(mPriority));
-}
-
 } // namespace
 
 namespace mozilla {
 
 /* static */ void
 ProcessPriorityManager::Init()
 {
   ProcessPriorityManagerImpl::StaticInit();
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -846,21 +846,21 @@ NotifySwitchChange(const SwitchEvent& aE
   if (!sSwitchObserverLists)
     return;
 
   SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
   observer.Broadcast(aEvent);
 }
 
 void
-SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
+SetProcessPriority(int aPid, ProcessPriority aPriority)
 {
   // n.b. The sandboxed implementation crashes; SetProcessPriority works only
   // from the main process.
-  PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority, aLRU));
+  PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
 }
 
 void
 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
 {
   PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
 }
 
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -432,19 +432,17 @@ void NotifySwitchStateFromInputDevice(ha
 
 /**
  * Set the priority of the given process.
  *
  * Exactly what this does will vary between platforms.  On *nix we might give
  * background processes higher nice values.  On other platforms, we might
  * ignore this call entirely.
  */
-void SetProcessPriority(int aPid,
-                        hal::ProcessPriority aPriority,
-                        uint32_t aLRU = 0);
+void SetProcessPriority(int aPid, hal::ProcessPriority aPriority);
 
 
 /**
  * Set the current thread's priority to appropriate platform-specific value for
  * given functionality. Instead of providing arbitrary priority numbers you
  * must specify a type of function like THREAD_PRIORITY_COMPOSITOR.
  */
 void SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority);
--- a/hal/fallback/FallbackProcessPriority.cpp
+++ b/hal/fallback/FallbackProcessPriority.cpp
@@ -6,16 +6,16 @@
 #include "HalLog.h"
 
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal_impl {
 
 void
-SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
+SetProcessPriority(int aPid, ProcessPriority aPriority)
 {
-  HAL_LOG("FallbackProcessPriority - SetProcessPriority(%d, %s, %u)\n",
-          aPid, ProcessPriorityToString(aPriority), aLRU);
+  HAL_LOG("FallbackProcessPriority - SetProcessPriority(%d, %s)\n",
+          aPid, ProcessPriorityToString(aPriority));
 }
 
 } // namespace hal_impl
 } // namespace mozilla
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -344,17 +344,17 @@ DisableAlarm()
 bool
 SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
 {
   NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts.  Yet.");
   return false;
 }
 
 void
-SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
+SetProcessPriority(int aPid, ProcessPriority aPriority)
 {
   NS_RUNTIMEABORT("Only the main process may set processes' priorities.");
 }
 
 void
 SetCurrentThreadPriority(ThreadPriority aThreadPriority)
 {
   NS_RUNTIMEABORT("Setting current thread priority cannot be called from sandboxed contexts.");