| Index: components/memory_pressure/memory_pressure_monitor.cc
|
| diff --git a/components/memory_pressure/memory_pressure_monitor.cc b/components/memory_pressure/memory_pressure_monitor.cc
|
| deleted file mode 100644
|
| index a0f67a8fa3179316f16eaf587a4c031f146ac4ce..0000000000000000000000000000000000000000
|
| --- a/components/memory_pressure/memory_pressure_monitor.cc
|
| +++ /dev/null
|
| @@ -1,283 +0,0 @@
|
| -// Copyright 2016 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/memory_pressure_monitor.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/location.h"
|
| -#include "base/task_runner.h"
|
| -#include "base/time/tick_clock.h"
|
| -#include "components/memory_pressure/memory_pressure_calculator.h"
|
| -#include "components/memory_pressure/memory_pressure_stats_collector.h"
|
| -
|
| -namespace memory_pressure {
|
| -
|
| -namespace {
|
| -
|
| -using MemoryPressureLevel = MemoryPressureMonitor::MemoryPressureLevel;
|
| -const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_NONE =
|
| - MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
| -const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_MODERATE =
|
| - MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
|
| -const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_CRITICAL =
|
| - MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
|
| -
|
| -// Returns the polling/notification interval for the given pressure level.
|
| -int GetPollingIntervalMs(MemoryPressureLevel level) {
|
| - switch (level) {
|
| - case MEMORY_PRESSURE_LEVEL_NONE:
|
| - return MemoryPressureMonitor::kDefaultPollingIntervalMs;
|
| -
|
| - case MEMORY_PRESSURE_LEVEL_MODERATE:
|
| - return MemoryPressureMonitor::kNotificationIntervalPressureModerateMs;
|
| -
|
| - case MEMORY_PRESSURE_LEVEL_CRITICAL:
|
| - return MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs;
|
| - }
|
| -
|
| - NOTREACHED();
|
| - return 0;
|
| -}
|
| -
|
| -base::TimeDelta GetPollingInterval(MemoryPressureLevel level) {
|
| - return base::TimeDelta::FromMilliseconds(GetPollingIntervalMs(level));
|
| -}
|
| -
|
| -// Serial number reserved for unscheduled checks as a result of external calls
|
| -// to the monitor.
|
| -const int kUnscheduledCheckSerial = 0;
|
| -
|
| -} // namespace
|
| -
|
| -#if !defined(MEMORY_PRESSURE_IS_POLLING)
|
| -// Default definition of this class.
|
| -// TODO(chrisha): Implement useful versions of this for affected platforms.
|
| -class MemoryPressureMonitorImpl {};
|
| -#endif
|
| -
|
| -#if defined(MEMORY_PRESSURE_IS_POLLING)
|
| -MemoryPressureMonitor::MemoryPressureMonitor(
|
| - const scoped_refptr<base::TaskRunner>& task_runner,
|
| - base::TickClock* tick_clock,
|
| - MemoryPressureStatsCollector* stats_collector,
|
| - MemoryPressureCalculator* calculator,
|
| - const DispatchCallback& dispatch_callback)
|
| - : task_runner_(task_runner),
|
| - tick_clock_(tick_clock),
|
| - stats_collector_(stats_collector),
|
| - calculator_(calculator),
|
| - dispatch_callback_(dispatch_callback),
|
| - current_memory_pressure_level_(MEMORY_PRESSURE_LEVEL_NONE),
|
| - serial_number_(kUnscheduledCheckSerial),
|
| - weak_ptr_factory_(this) {
|
| - DCHECK(task_runner_.get());
|
| - DCHECK(tick_clock_);
|
| - DCHECK(stats_collector_);
|
| - DCHECK(calculator_);
|
| - DCHECK(!dispatch_callback_.is_null());
|
| -
|
| - Start();
|
| -}
|
| -#else // MEMORY_PRESSURE_IS_POLLING
|
| -MemoryPressureMonitor::MemoryPressureMonitor(
|
| - const scoped_refptr<base::TaskRunner>& task_runner,
|
| - base::TickClock* tick_clock,
|
| - MemoryPressureStatsCollector* stats_collector,
|
| - const DispatchCallback& dispatch_callback,
|
| - MemoryPressureLevel initial_pressure_level)
|
| - : task_runner_(task_runner),
|
| - tick_clock_(tick_clock),
|
| - stats_collector_(stats_collector),
|
| - dispatch_callback_(dispatch_callback),
|
| - current_memory_pressure_level_(initial_pressure_level),
|
| - serial_number_(kUnscheduledCheckSerial),
|
| - weak_ptr_factory_(this) {
|
| - DCHECK(task_runner_.get());
|
| - DCHECK(tick_clock_);
|
| - DCHECK(stats_collector_);
|
| - DCHECK(!dispatch_callback_.is_null());
|
| -
|
| - Start();
|
| -}
|
| -#endif // !MEMORY_PRESSURE_IS_POLLING
|
| -
|
| -MemoryPressureMonitor::~MemoryPressureMonitor() {}
|
| -
|
| -MemoryPressureLevel MemoryPressureMonitor::GetCurrentPressureLevel() {
|
| - base::AutoLock lock(lock_);
|
| -
|
| -#if defined(MEMORY_PRESSURE_IS_POLLING)
|
| - // Force an immediate pressure check on polling platforms. On non-polling
|
| - // platforms the current memory pressure is always valid.
|
| - CheckPressureAndUpdateStatsLocked(kUnscheduledCheckSerial);
|
| -#endif
|
| -
|
| - return current_memory_pressure_level_;
|
| -}
|
| -
|
| -void MemoryPressureMonitor::CheckMemoryPressureSoon() {
|
| - // This function is a nop on non-polling platforms.
|
| -#if defined(MEMORY_PRESSURE_IS_POLLING)
|
| - // Schedule a check to run as soon as possible.
|
| - base::AutoLock lock(lock_);
|
| - base::TimeTicks now = tick_clock_->NowTicks();
|
| - ScheduleTaskLocked(now);
|
| -#endif
|
| -}
|
| -
|
| -#if !defined(MEMORY_PRESSURE_IS_POLLING)
|
| -// This is the entry point for OS notifications of pressure level changes.
|
| -void MemoryPressureMonitor::OnMemoryPressureChanged(
|
| - MemoryPressureLevel level) {
|
| - base::AutoLock lock(lock_);
|
| -
|
| - // Do nothing if the level hasn't changed.
|
| - if (level == current_memory_pressure_level_)
|
| - return;
|
| -
|
| - // Update the level and the stats.
|
| - current_memory_pressure_level_ = level;
|
| - stats_collector_->UpdateStatistics(current_memory_pressure_level_);
|
| -
|
| - // Only dispatch notifications if there is memory pressure.
|
| - if (current_memory_pressure_level_ > MEMORY_PRESSURE_LEVEL_NONE) {
|
| - last_notification_ = tick_clock_->NowTicks();
|
| - dispatch_callback_.Run(current_memory_pressure_level_);
|
| - }
|
| -
|
| - ScheduleTaskIfNeededLocked(kUnscheduledCheckSerial);
|
| -}
|
| -#endif
|
| -
|
| -void MemoryPressureMonitor::Start() {
|
| - base::AutoLock lock(lock_);
|
| -
|
| - base::TimeTicks now = tick_clock_->NowTicks();
|
| -
|
| - // Get the statistics collector warmed up by measuring the pressure level.
|
| - // Don't immediately fire a signal if already under memory pressure as the
|
| - // system is quite busy with startup right now. Wait until the first
|
| - // renotification is required, allowing the browser time to get started.
|
| - // Non-polling implementations set the initial memory pressure level in the
|
| - // constructor.
|
| -#if defined(MEMORY_PRESSURE_IS_POLLING)
|
| - current_memory_pressure_level_ = calculator_->CalculateCurrentPressureLevel();
|
| - last_check_ = now;
|
| -#endif
|
| -
|
| - last_notification_ = now;
|
| - stats_collector_->UpdateStatistics(current_memory_pressure_level_);
|
| - ScheduleTaskIfNeededLocked(kUnscheduledCheckSerial);
|
| -}
|
| -
|
| -void MemoryPressureMonitor::CheckPressureAndUpdateStats(int serial) {
|
| - // This should only ever be used by scheduled checks.
|
| - DCHECK_NE(kUnscheduledCheckSerial, serial);
|
| - base::AutoLock lock(lock_);
|
| - CheckPressureAndUpdateStatsLocked(serial);
|
| -}
|
| -
|
| -void MemoryPressureMonitor::CheckPressureAndUpdateStatsLocked(int serial) {
|
| - lock_.AssertAcquired();
|
| -
|
| - base::TimeTicks now = tick_clock_->NowTicks();
|
| - MemoryPressureLevel old_level = current_memory_pressure_level_;
|
| -
|
| -#if defined(MEMORY_PRESSURE_IS_POLLING)
|
| - // Don't check again if pressure was calculated too recently.
|
| - DCHECK(!last_check_.is_null());
|
| - if ((now - last_check_) >=
|
| - base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSamplesMs)) {
|
| - // Calculate the current pressure level and update statistics.
|
| - last_check_ = now;
|
| - current_memory_pressure_level_ =
|
| - calculator_->CalculateCurrentPressureLevel();
|
| - stats_collector_->UpdateStatistics(current_memory_pressure_level_);
|
| - }
|
| -#else // MEMORY_PRESSURE_IS_POLLING
|
| - // On non-polling platforms this function can only be invoked by scheduled
|
| - // callbacks for updating statistics and sending renotifications. Simply
|
| - // update the statistics and move on.
|
| - DCHECK_NE(kUnscheduledCheckSerial, serial);
|
| - stats_collector_->UpdateStatistics(current_memory_pressure_level_);
|
| -#endif // !MEMORY_PRESSURE_IS_POLLING
|
| -
|
| - // Check if the level has changed or a renotification is required.
|
| - DCHECK(!last_notification_.is_null());
|
| - if (current_memory_pressure_level_ != old_level ||
|
| - now - last_notification_ >=
|
| - GetPollingInterval(current_memory_pressure_level_)) {
|
| - last_notification_ = now;
|
| -
|
| - // Only dispatch notifications if there is memory pressure.
|
| - if (current_memory_pressure_level_ > MEMORY_PRESSURE_LEVEL_NONE)
|
| - dispatch_callback_.Run(current_memory_pressure_level_);
|
| - }
|
| -
|
| - ScheduleTaskIfNeededLocked(serial);
|
| -}
|
| -
|
| -void MemoryPressureMonitor::ScheduleTaskIfNeededLocked(int serial) {
|
| - lock_.AssertAcquired();
|
| -
|
| - // Remove this check from the set of scheduled checks.
|
| - if (serial != kUnscheduledCheckSerial) {
|
| - size_t erased = scheduled_checks_.erase(serial);
|
| - DCHECK_EQ(1u, erased);
|
| - }
|
| -
|
| - // Get the time of the soonest scheduled check. This linear scan is quick
|
| - // because the map will contain at most 1 entry per pressure level, and most
|
| - // commonly only 1 entry.
|
| - base::TimeTicks next_check;
|
| - for (const auto& check : scheduled_checks_) {
|
| - if (next_check.is_null() || check.second < next_check)
|
| - next_check = check.second;
|
| - }
|
| -
|
| - // Get the time of the required next check.
|
| - base::TimeTicks required_check =
|
| - last_notification_ + GetPollingInterval(current_memory_pressure_level_);
|
| -
|
| - // If there's already a check scheduled in time then don't schedule
|
| - // another. This lets the number of scheduled checks shrink back down to 1
|
| - // as pressure changes occur.
|
| - if (!next_check.is_null() && next_check <= required_check)
|
| - return;
|
| -
|
| - ScheduleTaskLocked(required_check);
|
| -}
|
| -
|
| -void MemoryPressureMonitor::ScheduleTaskLocked(base::TimeTicks when) {
|
| - lock_.AssertAcquired();
|
| - int serial = ++serial_number_;
|
| -
|
| - // Handle overflow. For simplicity keep serial numbers positive. 2^31 leaves
|
| - // room for 20 years of uptime in the worst case scenario (poll every second,
|
| - // constantly swinging through all the pressure levels). But you know...
|
| - // better safe the sorry!
|
| - if (serial < 0) {
|
| - serial_number_ = 1;
|
| - serial = 1;
|
| - }
|
| -
|
| - // It's entirely possible for |when| to be in the past relative to |now|, so
|
| - // bound |delay| from below.
|
| - base::TimeTicks now = tick_clock_->NowTicks();
|
| - base::TimeDelta delay; // Initializes to zero.
|
| - if (when > now)
|
| - delay = when - now;
|
| -
|
| - // Schedule another check.
|
| - if (task_runner_->PostDelayedTask(
|
| - FROM_HERE,
|
| - base::Bind(&MemoryPressureMonitor::CheckPressureAndUpdateStats,
|
| - weak_ptr_factory_.GetWeakPtr(), serial),
|
| - delay)) {
|
| - // If the task will run then add it to the map of scheduled checks.
|
| - scheduled_checks_[serial] = when;
|
| - }
|
| -}
|
| -
|
| -} // namespace memory_pressure
|
|
|