Bug 1212833 - Delay the MemoryPressure when an application goes to background. r=gsvelto
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -688,16 +688,17 @@ pref("layout.css.scroll-snap.enabled", t
// Enable the ProcessPriorityManager, and give processes with no visible
// documents a 1s grace period before they're eligible to be marked as
// background. Background processes that are perceivable due to playing
// media are given a longer grace period to accomodate changing tracks, etc.
pref("dom.ipc.processPriorityManager.enabled", true);
pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
+pref("dom.ipc.processPriorityManager.memoryPressureGracePeriodMS", 3000);
pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
// Number of different background/foreground levels for background/foreground
// processes. We use these different levels to force the low-memory killer to
// kill processes in a LRU order.
pref("dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels", 5);
pref("dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels", 4);
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -341,16 +341,17 @@ public:
void Freeze();
void Unfreeze();
void ShutDown();
private:
static uint32_t sBackgroundPerceivableGracePeriodMS;
static uint32_t sBackgroundGracePeriodMS;
+ static uint32_t sMemoryPressureGracePeriodMS;
void FireTestOnlyObserverNotification(
const char* aTopic,
const nsACString& aData = EmptyCString());
void FireTestOnlyObserverNotification(
const char* aTopic,
const char* aData = nullptr);
@@ -365,28 +366,30 @@ private:
bool mFrozen;
/**
* Used to implement NameWithComma().
*/
nsAutoCString mNameWithComma;
nsCOMPtr<nsITimer> mResetPriorityTimer;
+ nsCOMPtr<nsITimer> mMemoryPressureTimer;
};
/* static */ bool ProcessPriorityManagerImpl::sInitialized = false;
/* static */ bool ProcessPriorityManagerImpl::sPrefsEnabled = false;
/* static */ bool ProcessPriorityManagerImpl::sRemoteTabsDisabled = true;
/* static */ bool ProcessPriorityManagerImpl::sTestMode = false;
/* static */ bool ProcessPriorityManagerImpl::sPrefListenersRegistered = false;
/* static */ bool ProcessPriorityManagerImpl::sFrozen = false;
/* static */ StaticRefPtr<ProcessPriorityManagerImpl>
ProcessPriorityManagerImpl::sSingleton;
/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundPerceivableGracePeriodMS = 0;
/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundGracePeriodMS = 0;
+/* static */ uint32_t ParticularProcessPriorityManager::sMemoryPressureGracePeriodMS = 0;
NS_IMPL_ISUPPORTS(ProcessPriorityManagerImpl,
nsIObserver,
nsISupportsWeakReference);
/* static */ void
ProcessPriorityManagerImpl::PrefChangedCallback(const char* aPref,
void* aClosure)
@@ -696,16 +699,18 @@ ParticularProcessPriorityManager::Partic
void
ParticularProcessPriorityManager::StaticInit()
{
Preferences::AddUintVarCache(&sBackgroundPerceivableGracePeriodMS,
"dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS");
Preferences::AddUintVarCache(&sBackgroundGracePeriodMS,
"dom.ipc.processPriorityManager.backgroundGracePeriodMS");
+ Preferences::AddUintVarCache(&sMemoryPressureGracePeriodMS,
+ "dom.ipc.processPriorityManager.memoryPressureGracePeriodMS");
}
void
ParticularProcessPriorityManager::Init()
{
RegisterWakeLockObserver(this);
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
@@ -1009,20 +1014,31 @@ ParticularProcessPriorityManager::Schedu
LOGP("Scheduling reset timer to fire in %dms.", timeout);
mResetPriorityTimer = do_CreateInstance("@mozilla.org/timer;1");
mResetPriorityTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
}
NS_IMETHODIMP
ParticularProcessPriorityManager::Notify(nsITimer* aTimer)
{
- LOGP("Reset priority timer callback; about to ResetPriorityNow.");
- ResetPriorityNow();
- mResetPriorityTimer = nullptr;
- return NS_OK;
+ if (mResetPriorityTimer == aTimer) {
+ LOGP("Reset priority timer callback; about to ResetPriorityNow.");
+ ResetPriorityNow();
+ mResetPriorityTimer = nullptr;
+ return NS_OK;
+ }
+
+ if (mContentParent && mMemoryPressureTimer == aTimer) {
+ Unused << mContentParent->SendFlushMemory(NS_LITERAL_STRING("lowering-priority"));
+ mMemoryPressureTimer = nullptr;
+ return NS_OK;
+ }
+
+ NS_WARNING("Unexpected timer!");
+ return NS_ERROR_INVALID_POINTER;
}
bool
ParticularProcessPriorityManager::HasAppType(const char* aAppType)
{
const ManagedContainer<PBrowserParent>& browsers =
mContentParent->ManagedPBrowserParent();
for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
@@ -1137,20 +1153,28 @@ ParticularProcessPriorityManager::SetPri
mPriority = aPriority;
hal::SetProcessPriority(Pid(), mPriority);
if (oldPriority != mPriority) {
ProcessPriorityManagerImpl::GetSingleton()->
NotifyProcessPriorityChanged(this, oldPriority);
Unused << mContentParent->SendNotifyProcessPriorityChanged(mPriority);
- }
+
+ if (mMemoryPressureTimer) {
+ mMemoryPressureTimer->Cancel();
+ mMemoryPressureTimer = nullptr;
+ }
- if (aPriority < PROCESS_PRIORITY_FOREGROUND) {
- Unused << mContentParent->SendFlushMemory(NS_LITERAL_STRING("lowering-priority"));
+ if (aPriority < PROCESS_PRIORITY_FOREGROUND) {
+ mMemoryPressureTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
+ mMemoryPressureTimer->InitWithCallback(this,
+ sMemoryPressureGracePeriodMS,
+ nsITimer::TYPE_ONE_SHOT);
+ }
}
FireTestOnlyObserverNotification("process-priority-set",
ProcessPriorityToString(mPriority));
}
void
ParticularProcessPriorityManager::Freeze()