Bug 670967 - Part 1: Add mozilla::ScheduleMemoryPressureEvent(). r=bsmedberg

This commit is contained in:
Justin Lebar
2011-08-05 18:10:50 -04:00
parent 8711e0bcbb
commit 01e313044d
3 changed files with 48 additions and 0 deletions

View File

@@ -64,6 +64,7 @@ CPPSRCS = \
$(NULL) $(NULL)
EXPORTS = \ EXPORTS = \
nsThread.h \
nsProcess.h \ nsProcess.h \
nsEventQueue.h \ nsEventQueue.h \
nsThreadUtilsInternal.h \ nsThreadUtilsInternal.h \

View File

@@ -45,7 +45,9 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "prlog.h" #include "prlog.h"
#include "nsThreadUtilsInternal.h" #include "nsThreadUtilsInternal.h"
#include "nsIObserverService.h"
#include "mozilla/HangMonitor.h" #include "mozilla/HangMonitor.h"
#include "mozilla/Services.h"
#define HAVE_UALARM _BSD_SOURCE || (_XOPEN_SOURCE >= 500 || \ #define HAVE_UALARM _BSD_SOURCE || (_XOPEN_SOURCE >= 500 || \
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \ _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \
@@ -81,6 +83,23 @@ NS_DECL_CI_INTERFACE_GETTER(nsThread)
nsIThreadObserver* nsThread::sGlobalObserver; nsIThreadObserver* nsThread::sGlobalObserver;
namespace mozilla {
// Fun fact: Android's GCC won't convert bool* to PRInt32*, so we can't
// PR_ATOMIC_SET a bool.
static PRInt32 sMemoryPressurePending = 0;
/*
* It's important that this function not acquire any locks, nor do anything
* which might cause malloc to run.
*/
void ScheduleMemoryPressureEvent()
{
PR_ATOMIC_SET(&sMemoryPressurePending, 1);
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Because we do not have our own nsIFactory, we have to implement nsIClassInfo // Because we do not have our own nsIFactory, we have to implement nsIClassInfo
// somewhat manually. // somewhat manually.
@@ -577,6 +596,22 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
if (MAIN_THREAD == mIsMainThread && mayWait && !ShuttingDown()) if (MAIN_THREAD == mIsMainThread && mayWait && !ShuttingDown())
HangMonitor::Suspend(); HangMonitor::Suspend();
// Fire a memory pressure notification, if we're the main thread and one is
// pending.
if (MAIN_THREAD == mIsMainThread && !ShuttingDown()) {
bool mpPending = PR_ATOMIC_SET(&sMemoryPressurePending, 0);
if (mpPending) {
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(nsnull, "memory-pressure",
NS_LITERAL_STRING("low-memory").get());
}
else {
NS_WARNING("Can't get observer service!");
}
}
}
bool notifyGlobalObserver = (sGlobalObserver != nsnull); bool notifyGlobalObserver = (sGlobalObserver != nsnull);
if (notifyGlobalObserver) if (notifyGlobalObserver)
sGlobalObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(), sGlobalObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(),

View File

@@ -178,4 +178,16 @@ private:
nsresult mResult; nsresult mResult;
}; };
namespace mozilla {
/**
* This function causes the main thread to fire a memory pressure event at its
* next available opportunity.
*
* You may call this function from any thread.
*/
void ScheduleMemoryPressureEvent();
} // namespace mozilla
#endif // nsThread_h__ #endif // nsThread_h__