blob: 4c76ce93c349ee5aca410e3d221099d4a02c1b89 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/memory_pressure/multi_source_memory_pressure_monitor.h"
#include "base/bind.h"
#include "base/check_op.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "base/trace_event/base_tracing.h"
#include "base/tracing_buildflags.h"
#include "components/memory_pressure/system_memory_pressure_evaluator.h"
#if BUILDFLAG(ENABLE_BASE_TRACING)
#include "base/trace_event/memory_pressure_level_proto.h" // no-presubmit-check
#endif
namespace memory_pressure {
MultiSourceMemoryPressureMonitor::MultiSourceMemoryPressureMonitor()
: current_pressure_level_(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
dispatch_callback_(base::BindRepeating(
&base::MemoryPressureListener::NotifyMemoryPressure)),
aggregator_(this),
level_reporter_(current_pressure_level_) {}
MultiSourceMemoryPressureMonitor::~MultiSourceMemoryPressureMonitor() {
// Destroy system evaluator early while the remaining members of this class
// still exist. MultiSourceMemoryPressureMonitor implements
// MemoryPressureVoteAggregator::Delegate, and
// delegate_->OnMemoryPressureLevelChanged() gets indirectly called during
// ~SystemMemoryPressureEvaluator().
system_evaluator_.reset();
}
void MultiSourceMemoryPressureMonitor::Start() {
system_evaluator_ =
SystemMemoryPressureEvaluator::CreateDefaultSystemEvaluator(this);
}
base::MemoryPressureListener::MemoryPressureLevel
MultiSourceMemoryPressureMonitor::GetCurrentPressureLevel() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return current_pressure_level_;
}
std::unique_ptr<MemoryPressureVoter>
MultiSourceMemoryPressureMonitor::CreateVoter() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return aggregator_.CreateVoter();
}
void MultiSourceMemoryPressureMonitor::SetDispatchCallback(
const DispatchCallback& callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dispatch_callback_ = callback;
}
void MultiSourceMemoryPressureMonitor::OnMemoryPressureLevelChanged(
base::MemoryPressureListener::MemoryPressureLevel level) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_NE(current_pressure_level_, level);
level_reporter_.OnMemoryPressureLevelChanged(level);
TRACE_EVENT_INSTANT(
"base", "MultiSourceMemoryPressureMonitor::OnMemoryPressureLevelChanged",
[&](perfetto::EventContext ctx) {
auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
auto* data = event->set_chrome_memory_pressure_notification();
data->set_level(
base::trace_event::MemoryPressureLevelToTraceEnum(level));
});
current_pressure_level_ = level;
}
void MultiSourceMemoryPressureMonitor::OnNotifyListenersRequested() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dispatch_callback_.Run(current_pressure_level_);
}
void MultiSourceMemoryPressureMonitor::ResetSystemEvaluatorForTesting() {
system_evaluator_.reset();
}
void MultiSourceMemoryPressureMonitor::SetSystemEvaluator(
std::unique_ptr<SystemMemoryPressureEvaluator> evaluator) {
DCHECK(!system_evaluator_);
system_evaluator_ = std::move(evaluator);
}
} // namespace memory_pressure