Bug 873284 - When a content process is running at high priority do not send memory-pressure events. r=khuey

This commit is contained in:
Gabriele Svelto 2014-02-17 17:45:29 +01:00
parent 1c758b19bd
commit 6b12580552
3 changed files with 60 additions and 4 deletions

View File

@ -102,8 +102,9 @@ class ParticularProcessPriorityManager;
* can call StaticInit, but it won't do anything, and GetSingleton() will
* return null.)
*
* ProcessPriorityManager::CurrentProcessIsForeground(), which can be called in
* any process, is handled separately, by the ProcessPriorityManagerChild
* ProcessPriorityManager::CurrentProcessIsForeground() and
* ProcessPriorityManager::AnyProcessHasHighPriority() which can be called in
* any process, are handled separately, by the ProcessPriorityManagerChild
* class.
*/
class ProcessPriorityManagerImpl MOZ_FINAL
@ -143,6 +144,11 @@ public:
bool OtherProcessHasHighPriority(
ParticularProcessPriorityManager* aParticularManager);
/**
* Does one of the child processes have priority FOREGROUND_HIGH?
*/
bool ChildProcessHasHighPriority();
/**
* This must be called by a ParticularProcessPriorityManager when it changes
* its priority.
@ -191,6 +197,7 @@ public:
NS_DECL_NSIOBSERVER
bool CurrentProcessIsForeground();
bool CurrentProcessIsHighPriority();
private:
static StaticRefPtr<ProcessPriorityManagerChild> sSingleton;
@ -540,6 +547,12 @@ ProcessPriorityManagerImpl::OtherProcessHasHighPriority(
return mHighPriorityChildIDs.Count() > 0;
}
bool
ProcessPriorityManagerImpl::ChildProcessHasHighPriority( void )
{
return mHighPriorityChildIDs.Count() > 0;
}
void
ProcessPriorityManagerImpl::NotifyProcessPriorityChanged(
ParticularProcessPriorityManager* aParticularManager,
@ -1204,6 +1217,13 @@ ProcessPriorityManagerChild::CurrentProcessIsForeground()
mCachedPriority >= PROCESS_PRIORITY_FOREGROUND;
}
bool
ProcessPriorityManagerChild::CurrentProcessIsHighPriority()
{
return mCachedPriority == PROCESS_PRIORITY_UNKNOWN ||
mCachedPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH;
}
/* static */ StaticAutoPtr<BackgroundProcessLRUPool>
BackgroundProcessLRUPool::sSingleton;
@ -1435,4 +1455,18 @@ ProcessPriorityManager::CurrentProcessIsForeground()
CurrentProcessIsForeground();
}
/* static */ bool
ProcessPriorityManager::AnyProcessHasHighPriority()
{
ProcessPriorityManagerImpl* singleton =
ProcessPriorityManagerImpl::GetSingleton();
if (singleton) {
return singleton->ChildProcessHasHighPriority();
} else {
return ProcessPriorityManagerChild::Singleton()->
CurrentProcessIsHighPriority();
}
}
} // namespace mozilla

View File

@ -68,6 +68,12 @@ public:
*/
static bool CurrentProcessIsForeground();
/**
* Returns true if one or more processes with FOREGROUND_HIGH priority are
* present, false otherwise.
*/
static bool AnyProcessHasHighPriority();
/**
* Used to remove a ContentParent from background LRU pool when
* it is destroyed or its priority changed from BACKGROUND to others.

View File

@ -9,6 +9,7 @@
#include "mozilla/FileUtils.h"
#include "mozilla/Monitor.h"
#include "mozilla/Preferences.h"
#include "mozilla/ProcessPriorityManager.h"
#include "mozilla/Services.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
@ -169,7 +170,7 @@ public:
// We use low-memory-no-forward because each process has its own watcher
// and thus there is no need for the main process to forward this event.
rv = NS_DispatchMemoryPressure(MemPressure_New);
rv = DispatchMemoryPressure(MemPressure_New);
NS_ENSURE_SUCCESS(rv, rv);
// Manually check lowMemFd until we observe that memory pressure is over.
@ -202,7 +203,7 @@ public:
NS_ENSURE_SUCCESS(rv, rv);
if (memoryPressure) {
rv = NS_DispatchMemoryPressure(MemPressure_Ongoing);
rv = DispatchMemoryPressure(MemPressure_Ongoing);
NS_ENSURE_SUCCESS(rv, rv);
continue;
}
@ -245,6 +246,21 @@ private:
return NS_OK;
}
/**
* Dispatch the specified memory pressure event unless a high-priority
* process is present. If a high-priority process is present then it's likely
* responding to an urgent event (an incoming call or message for example) so
* avoid wasting CPU time responding to low-memory events.
*/
nsresult DispatchMemoryPressure(MemoryPressureState state)
{
if (ProcessPriorityManager::AnyProcessHasHighPriority()) {
return NS_OK;
}
return NS_DispatchMemoryPressure(state);
}
Monitor mMonitor;
uint32_t mPollMS;
bool mShuttingDown;