gecko-dev/xpcom/threads/nsMemoryPressure.cpp
Jan Henning 991ff633f3 Bug 1335148 - Part 2: Introduce notification for end of memory pressure. r=gsvelto,snorp
For Fennec on Android, if we haven't received memory pressure notifications from
the OS for a certain amount of time (in the order of ~15 mins), we assume that
we're no longer under memory pressure. In order to turn the bfcache back on when
that happens, we now want to be able to forward this fact to Gecko as well.

Unfortunately, the way memory pressure is tracked using an atomic variable
doesn't easily allow to fully extend the existing priority rules between "new"
and "ongoing" to include a new "stopping of memory pressure" event. Since we're
not using Dispatch*Eventual*MemoryPressure on Android and therefore the queuing
priority behaviour isn't actually relevant for us, we just ignore that and only
enforce that a pending "new" memory pressure event takes priority over a "stop"
event.

MozReview-Commit-ID: 90C9KogUyvf

--HG--
extra : rebase_source : 4e71a31433557d8d486f941953717a88d5d87e7d
2018-03-30 13:26:24 +02:00

56 lines
1.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsMemoryPressure.h"
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "nsThreadUtils.h"
using namespace mozilla;
static Atomic<int32_t, Relaxed> sMemoryPressurePending;
static_assert(MemPressure_None == 0,
"Bad static initialization with the default constructor.");
MemoryPressureState
NS_GetPendingMemoryPressure()
{
int32_t value = sMemoryPressurePending.exchange(MemPressure_None);
return MemoryPressureState(value);
}
void
NS_DispatchEventualMemoryPressure(MemoryPressureState aState)
{
/*
* A new memory pressure event erases an ongoing (or stop of) memory pressure,
* but an existing "new" memory pressure event takes precedence over a new
* "ongoing" or "stop" memory pressure event.
*/
switch (aState) {
case MemPressure_None:
sMemoryPressurePending = MemPressure_None;
break;
case MemPressure_New:
sMemoryPressurePending = MemPressure_New;
break;
case MemPressure_Ongoing:
case MemPressure_Stopping:
sMemoryPressurePending.compareExchange(MemPressure_None,
aState);
break;
}
}
nsresult
NS_DispatchMemoryPressure(MemoryPressureState aState)
{
NS_DispatchEventualMemoryPressure(aState);
nsCOMPtr<nsIRunnable> event = new Runnable("NS_DispatchEventualMemoryPressure");
return NS_DispatchToMainThread(event);
}