| Index: base/memory/memory_pressure_monitor_mac.cc
|
| diff --git a/base/memory/memory_pressure_monitor_mac.cc b/base/memory/memory_pressure_monitor_mac.cc
|
| index d3430e94ca45a1ad9150c3cfe8f3342faf02ffe6..5ea381fd3bd4941987d7a7c471bca4b09b383723 100644
|
| --- a/base/memory/memory_pressure_monitor_mac.cc
|
| +++ b/base/memory/memory_pressure_monitor_mac.cc
|
| @@ -8,6 +8,8 @@
|
| #include <stddef.h>
|
| #include <sys/sysctl.h>
|
|
|
| +#include <cmath>
|
| +
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "base/mac/mac_util.h"
|
| @@ -33,29 +35,21 @@ MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
|
| return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
| }
|
|
|
| -void MemoryPressureMonitor::NotifyMemoryPressureChanged(
|
| - dispatch_source_s* event_source,
|
| - const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
|
| - int mac_memory_pressure = dispatch_source_get_data(event_source);
|
| - MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
|
| - MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
|
| - dispatch_callback.Run(memory_pressure_level);
|
| -}
|
| -
|
| MemoryPressureMonitor::MemoryPressureMonitor()
|
| - // The MemoryPressureListener doesn't want to know about transitions to
|
| - // MEMORY_PRESSURE_LEVEL_NONE so don't watch for
|
| - // DISPATCH_MEMORYPRESSURE_NORMAL notifications.
|
| : memory_level_event_source_(dispatch_source_create(
|
| DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
|
| 0,
|
| - DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
|
| + DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
|
| + DISPATCH_MEMORYPRESSURE_NORMAL,
|
| dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
|
| dispatch_callback_(
|
| - base::Bind(&MemoryPressureListener::NotifyMemoryPressure)) {
|
| + base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
|
| + last_pressure_change_(CFAbsoluteTimeGetCurrent()),
|
| + reporting_error_(0) {
|
| + last_pressure_level_ = GetCurrentPressureLevel();
|
| dispatch_source_set_event_handler(memory_level_event_source_, ^{
|
| - NotifyMemoryPressureChanged(memory_level_event_source_.get(),
|
| - dispatch_callback_);
|
| + OnMemoryPressureChanged(memory_level_event_source_.get(),
|
| + dispatch_callback_);
|
| });
|
| dispatch_resume(memory_level_event_source_);
|
| }
|
| @@ -72,6 +66,35 @@ MemoryPressureMonitor::GetCurrentPressureLevel() const {
|
| &length, nullptr, 0);
|
| return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
|
| }
|
| +void MemoryPressureMonitor::OnMemoryPressureChanged(
|
| + dispatch_source_s* event_source,
|
| + const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
|
| + int mac_memory_pressure = dispatch_source_get_data(event_source);
|
| + MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
|
| + MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
|
| + CFTimeInterval now = CFAbsoluteTimeGetCurrent();
|
| + CFTimeInterval since_last_change = now - last_pressure_change_;
|
| + last_pressure_change_ = now;
|
| +
|
| + double ticks_to_report;
|
| + reporting_error_ =
|
| + modf(since_last_change + reporting_error_, &ticks_to_report);
|
| +
|
| + // Sierra fails to call the handler when pressure returns to normal,
|
| + // which would skew our data. For example, if pressure went to 'warn'
|
| + // at T0, back to 'normal' at T1, then to 'critical' at T10, we would
|
| + // report 10 ticks of 'warn' instead of 1 tick of 'warn' and 9 ticks
|
| + // of 'normal'.
|
| + // This is rdar://29114314
|
| + if (mac::IsAtMostOS10_11())
|
| + RecordMemoryPressure(last_pressure_level_,
|
| + static_cast<int>(ticks_to_report));
|
| +
|
| + last_pressure_level_ = memory_pressure_level;
|
| + if (memory_pressure_level !=
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
|
| + dispatch_callback.Run(memory_pressure_level);
|
| +}
|
|
|
| void MemoryPressureMonitor::SetDispatchCallback(
|
| const DispatchCallback& callback) {
|
|
|