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

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: Fix parameter name in header 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
(...skipping 26 matching lines...) Expand all
37 37
38 MemoryPressureMonitor::MemoryPressureMonitor() 38 MemoryPressureMonitor::MemoryPressureMonitor()
39 : memory_level_event_source_(dispatch_source_create( 39 : memory_level_event_source_(dispatch_source_create(
40 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 40 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
41 0, 41 0,
42 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL | 42 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
43 DISPATCH_MEMORYPRESSURE_NORMAL, 43 DISPATCH_MEMORYPRESSURE_NORMAL,
44 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))), 44 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
45 dispatch_callback_( 45 dispatch_callback_(
46 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), 46 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
47 last_pressure_change_(CFAbsoluteTimeGetCurrent()), 47 last_statistic_report_(CFAbsoluteTimeGetCurrent()),
Mark Mentovai 2016/11/14 19:12:15 Is this an OK initial value? It’s not associated w
lgrey 2016/11/14 19:23:51 I think so. Worst case scenario is the application
48 last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
48 reporting_error_(0) { 49 reporting_error_(0) {
49 last_pressure_level_ = GetCurrentPressureLevel();
50 dispatch_source_set_event_handler(memory_level_event_source_, ^{ 50 dispatch_source_set_event_handler(memory_level_event_source_, ^{
51 OnMemoryPressureChanged(memory_level_event_source_.get(), 51 OnMemoryPressureChanged(memory_level_event_source_.get(),
52 dispatch_callback_); 52 dispatch_callback_);
53 }); 53 });
54 dispatch_resume(memory_level_event_source_); 54 dispatch_resume(memory_level_event_source_);
55 } 55 }
56 56
57 MemoryPressureMonitor::~MemoryPressureMonitor() { 57 MemoryPressureMonitor::~MemoryPressureMonitor() {
58 dispatch_source_cancel(memory_level_event_source_); 58 dispatch_source_cancel(memory_level_event_source_);
59 } 59 }
60 60
61 MemoryPressureListener::MemoryPressureLevel 61 MemoryPressureListener::MemoryPressureLevel
62 MemoryPressureMonitor::GetCurrentPressureLevel() const { 62 MemoryPressureMonitor::GetCurrentPressureLevel() {
63 int mac_memory_pressure; 63 int mac_memory_pressure;
64 size_t length = sizeof(int); 64 size_t length = sizeof(int);
65 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure, 65 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure,
66 &length, nullptr, 0); 66 &length, nullptr, 0);
67 return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); 67 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
68 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
69 bool pressure_level_changed = false;
70 if (last_pressure_level_ != memory_pressure_level) {
71 pressure_level_changed = true;
72 }
73 SendStatisticsIfNecessary(pressure_level_changed);
74 last_pressure_level_ = memory_pressure_level;
75 return memory_pressure_level;
68 } 76 }
77
69 void MemoryPressureMonitor::OnMemoryPressureChanged( 78 void MemoryPressureMonitor::OnMemoryPressureChanged(
70 dispatch_source_s* event_source, 79 dispatch_source_s* event_source,
71 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) { 80 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
72 int mac_memory_pressure = dispatch_source_get_data(event_source); 81 int mac_memory_pressure = dispatch_source_get_data(event_source);
73 MemoryPressureListener::MemoryPressureLevel memory_pressure_level = 82 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
74 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); 83 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
75 CFTimeInterval now = CFAbsoluteTimeGetCurrent(); 84 bool pressure_level_changed = false;
76 CFTimeInterval since_last_change = now - last_pressure_change_; 85 if (last_pressure_level_ != memory_pressure_level) {
77 last_pressure_change_ = now; 86 pressure_level_changed = true;
78 87 }
79 double ticks_to_report; 88 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; 89 last_pressure_level_ = memory_pressure_level;
94 if (memory_pressure_level != 90 if (memory_pressure_level !=
95 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) 91 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
96 dispatch_callback.Run(memory_pressure_level); 92 dispatch_callback.Run(memory_pressure_level);
97 } 93 }
98 94
95 void MemoryPressureMonitor::SendStatisticsIfNecessary(
96 bool pressure_level_changed) {
97 CFTimeInterval now = CFAbsoluteTimeGetCurrent();
98 CFTimeInterval since_last_report = now - last_statistic_report_;
99 last_statistic_report_ = now;
100
101 double ticks_to_report;
102 reporting_error_ =
103 modf(since_last_report + reporting_error_, &ticks_to_report);
Mark Mentovai 2016/11/14 19:12:15 Good practice is to not use modf(), but instead us
lgrey 2016/11/14 19:23:51 Done.
104
105 // Round up on change to ensure we capture it
106 if (pressure_level_changed && ticks_to_report < 0)
107 ticks_to_report = 1;
108
109 if (ticks_to_report > 0)
110 RecordMemoryPressure(last_pressure_level_,
111 static_cast<int>(ticks_to_report));
112 }
113
99 void MemoryPressureMonitor::SetDispatchCallback( 114 void MemoryPressureMonitor::SetDispatchCallback(
100 const DispatchCallback& callback) { 115 const DispatchCallback& callback) {
101 dispatch_callback_ = callback; 116 dispatch_callback_ = callback;
102 } 117 }
103 118
104 } // namespace mac 119 } // namespace mac
105 } // namespace base 120 } // 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