Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: base/memory/memory_pressure_monitor_mac.cc

Issue 2495003004: [Mac] Report statistics more regularly in Mac memory pressure monitor (Closed)
Patch Set: Report in 5 second ticks Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/memory_pressure_monitor_mac.h ('k') | base/memory/memory_pressure_monitor_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/memory_pressure_monitor_mac.h" 5 #include "base/memory/memory_pressure_monitor_mac.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <sys/sysctl.h> 9 #include <sys/sysctl.h>
10 10
11 #include <cmath> 11 #include <cmath>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/mac/mac_util.h" 15 #include "base/mac/mac_util.h"
16 16
17 // Redeclare for partial 10.9 availability. 17 // Redeclare for partial 10.9 availability.
18 DISPATCH_EXPORT const struct dispatch_source_type_s 18 DISPATCH_EXPORT const struct dispatch_source_type_s
19 _dispatch_source_type_memorypressure; 19 _dispatch_source_type_memorypressure;
20 20
21 namespace {
22 static const int kUMATickSize = 5;
23 } // namespace
24
21 namespace base { 25 namespace base {
22 namespace mac { 26 namespace mac {
23 27
24 MemoryPressureListener::MemoryPressureLevel 28 MemoryPressureListener::MemoryPressureLevel
25 MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure( 29 MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
26 int mac_memory_pressure) { 30 int mac_memory_pressure) {
27 switch (mac_memory_pressure) { 31 switch (mac_memory_pressure) {
28 case DISPATCH_MEMORYPRESSURE_NORMAL: 32 case DISPATCH_MEMORYPRESSURE_NORMAL:
29 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; 33 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
30 case DISPATCH_MEMORYPRESSURE_WARN: 34 case DISPATCH_MEMORYPRESSURE_WARN:
31 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE; 35 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
32 case DISPATCH_MEMORYPRESSURE_CRITICAL: 36 case DISPATCH_MEMORYPRESSURE_CRITICAL:
33 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; 37 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
34 } 38 }
35 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; 39 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
36 } 40 }
37 41
38 MemoryPressureMonitor::MemoryPressureMonitor() 42 MemoryPressureMonitor::MemoryPressureMonitor()
39 : memory_level_event_source_(dispatch_source_create( 43 : memory_level_event_source_(dispatch_source_create(
40 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 44 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
41 0, 45 0,
42 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL | 46 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
43 DISPATCH_MEMORYPRESSURE_NORMAL, 47 DISPATCH_MEMORYPRESSURE_NORMAL,
44 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))), 48 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
45 dispatch_callback_( 49 dispatch_callback_(
46 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), 50 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
47 last_pressure_change_(CFAbsoluteTimeGetCurrent()), 51 last_statistic_report_(CFAbsoluteTimeGetCurrent()),
52 last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
48 reporting_error_(0) { 53 reporting_error_(0) {
49 last_pressure_level_ = GetCurrentPressureLevel();
50 dispatch_source_set_event_handler(memory_level_event_source_, ^{ 54 dispatch_source_set_event_handler(memory_level_event_source_, ^{
51 OnMemoryPressureChanged(memory_level_event_source_.get(), 55 OnMemoryPressureChanged(memory_level_event_source_.get(),
52 dispatch_callback_); 56 dispatch_callback_);
53 }); 57 });
54 dispatch_resume(memory_level_event_source_); 58 dispatch_resume(memory_level_event_source_);
55 } 59 }
56 60
57 MemoryPressureMonitor::~MemoryPressureMonitor() { 61 MemoryPressureMonitor::~MemoryPressureMonitor() {
58 dispatch_source_cancel(memory_level_event_source_); 62 dispatch_source_cancel(memory_level_event_source_);
59 } 63 }
60 64
61 MemoryPressureListener::MemoryPressureLevel 65 MemoryPressureListener::MemoryPressureLevel
62 MemoryPressureMonitor::GetCurrentPressureLevel() const { 66 MemoryPressureMonitor::GetCurrentPressureLevel() {
63 int mac_memory_pressure; 67 int mac_memory_pressure;
64 size_t length = sizeof(int); 68 size_t length = sizeof(int);
65 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure, 69 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure,
66 &length, nullptr, 0); 70 &length, nullptr, 0);
67 return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); 71 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
72 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
73 bool pressure_level_changed = false;
74 if (last_pressure_level_ != memory_pressure_level) {
75 pressure_level_changed = true;
76 }
77 SendStatisticsIfNecessary(pressure_level_changed);
78 last_pressure_level_ = memory_pressure_level;
79 return memory_pressure_level;
68 } 80 }
81
69 void MemoryPressureMonitor::OnMemoryPressureChanged( 82 void MemoryPressureMonitor::OnMemoryPressureChanged(
70 dispatch_source_s* event_source, 83 dispatch_source_s* event_source,
71 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) { 84 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
72 int mac_memory_pressure = dispatch_source_get_data(event_source); 85 int mac_memory_pressure = dispatch_source_get_data(event_source);
73 MemoryPressureListener::MemoryPressureLevel memory_pressure_level = 86 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
74 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); 87 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
75 CFTimeInterval now = CFAbsoluteTimeGetCurrent(); 88 bool pressure_level_changed = false;
76 CFTimeInterval since_last_change = now - last_pressure_change_; 89 if (last_pressure_level_ != memory_pressure_level) {
77 last_pressure_change_ = now; 90 pressure_level_changed = true;
78 91 }
79 double ticks_to_report; 92 SendStatisticsIfNecessary(pressure_level_changed);
80 reporting_error_ =
81 modf(since_last_change + reporting_error_, &ticks_to_report);
82
83 // Sierra fails to call the handler when pressure returns to normal,
84 // which would skew our data. For example, if pressure went to 'warn'
85 // at T0, back to 'normal' at T1, then to 'critical' at T10, we would
86 // report 10 ticks of 'warn' instead of 1 tick of 'warn' and 9 ticks
87 // of 'normal'.
88 // This is rdar://29114314
89 if (mac::IsAtMostOS10_11())
90 RecordMemoryPressure(last_pressure_level_,
91 static_cast<int>(ticks_to_report));
92
93 last_pressure_level_ = memory_pressure_level; 93 last_pressure_level_ = memory_pressure_level;
94 if (memory_pressure_level != 94 if (memory_pressure_level !=
95 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) 95 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
96 dispatch_callback.Run(memory_pressure_level); 96 dispatch_callback.Run(memory_pressure_level);
97 } 97 }
98 98
99 void MemoryPressureMonitor::SendStatisticsIfNecessary(
100 bool pressure_level_changed) {
101 CFTimeInterval now = CFAbsoluteTimeGetCurrent();
102 CFTimeInterval since_last_report = now - last_statistic_report_;
103 last_statistic_report_ = now;
104
105 double accumulated_time = since_last_report + reporting_error_;
106 int ticks_to_report = static_cast<int>(accumulated_time / kUMATickSize);
107 reporting_error_ = std::fmod(accumulated_time, kUMATickSize);
108
109 // Round up on change to ensure we capture it
110 if (pressure_level_changed && ticks_to_report < 1) {
111 ticks_to_report = 1;
112 reporting_error_ = 0;
113 }
114
115 if (ticks_to_report >= 1)
116 RecordMemoryPressure(last_pressure_level_, ticks_to_report);
117 }
118
99 void MemoryPressureMonitor::SetDispatchCallback( 119 void MemoryPressureMonitor::SetDispatchCallback(
100 const DispatchCallback& callback) { 120 const DispatchCallback& callback) {
101 dispatch_callback_ = callback; 121 dispatch_callback_ = callback;
102 } 122 }
103 123
104 } // namespace mac 124 } // namespace mac
105 } // namespace base 125 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/memory_pressure_monitor_mac.h ('k') | base/memory/memory_pressure_monitor_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698