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

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

Issue 2434103003: Add Mac memory pressure statistic reporting and consolidate platform code (Closed)
Patch Set: Add radar ID 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
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>
12
11 #include "base/bind.h" 13 #include "base/bind.h"
12 #include "base/logging.h" 14 #include "base/logging.h"
13 #include "base/mac/mac_util.h" 15 #include "base/mac/mac_util.h"
14 16
15 // Redeclare for partial 10.9 availability. 17 // Redeclare for partial 10.9 availability.
16 DISPATCH_EXPORT const struct dispatch_source_type_s 18 DISPATCH_EXPORT const struct dispatch_source_type_s
17 _dispatch_source_type_memorypressure; 19 _dispatch_source_type_memorypressure;
18 20
19 namespace base { 21 namespace base {
20 namespace mac { 22 namespace mac {
21 23
22 MemoryPressureListener::MemoryPressureLevel 24 MemoryPressureListener::MemoryPressureLevel
23 MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure( 25 MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
24 int mac_memory_pressure) { 26 int mac_memory_pressure) {
25 switch (mac_memory_pressure) { 27 switch (mac_memory_pressure) {
26 case DISPATCH_MEMORYPRESSURE_NORMAL: 28 case DISPATCH_MEMORYPRESSURE_NORMAL:
27 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; 29 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
28 case DISPATCH_MEMORYPRESSURE_WARN: 30 case DISPATCH_MEMORYPRESSURE_WARN:
29 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE; 31 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
30 case DISPATCH_MEMORYPRESSURE_CRITICAL: 32 case DISPATCH_MEMORYPRESSURE_CRITICAL:
31 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; 33 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
32 } 34 }
33 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; 35 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
34 } 36 }
35 37
36 void MemoryPressureMonitor::NotifyMemoryPressureChanged(
37 dispatch_source_s* event_source,
38 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
39 int mac_memory_pressure = dispatch_source_get_data(event_source);
40 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
41 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
42 dispatch_callback.Run(memory_pressure_level);
43 }
44
45 MemoryPressureMonitor::MemoryPressureMonitor() 38 MemoryPressureMonitor::MemoryPressureMonitor()
46 // The MemoryPressureListener doesn't want to know about transitions to
47 // MEMORY_PRESSURE_LEVEL_NONE so don't watch for
48 // DISPATCH_MEMORYPRESSURE_NORMAL notifications.
49 : memory_level_event_source_(dispatch_source_create( 39 : memory_level_event_source_(dispatch_source_create(
50 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 40 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
51 0, 41 0,
52 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, 42 DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
43 DISPATCH_MEMORYPRESSURE_NORMAL,
53 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))), 44 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
54 dispatch_callback_( 45 dispatch_callback_(
55 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)) { 46 base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
47 last_pressure_change_(CFAbsoluteTimeGetCurrent()),
48 reporting_error_(0) {
49 last_pressure_level_ = GetCurrentPressureLevel();
56 dispatch_source_set_event_handler(memory_level_event_source_, ^{ 50 dispatch_source_set_event_handler(memory_level_event_source_, ^{
57 NotifyMemoryPressureChanged(memory_level_event_source_.get(), 51 OnMemoryPressureChanged(memory_level_event_source_.get(),
58 dispatch_callback_); 52 dispatch_callback_);
59 }); 53 });
60 dispatch_resume(memory_level_event_source_); 54 dispatch_resume(memory_level_event_source_);
61 } 55 }
62 56
63 MemoryPressureMonitor::~MemoryPressureMonitor() { 57 MemoryPressureMonitor::~MemoryPressureMonitor() {
64 dispatch_source_cancel(memory_level_event_source_); 58 dispatch_source_cancel(memory_level_event_source_);
65 } 59 }
66 60
67 MemoryPressureListener::MemoryPressureLevel 61 MemoryPressureListener::MemoryPressureLevel
68 MemoryPressureMonitor::GetCurrentPressureLevel() const { 62 MemoryPressureMonitor::GetCurrentPressureLevel() const {
69 int mac_memory_pressure; 63 int mac_memory_pressure;
70 size_t length = sizeof(int); 64 size_t length = sizeof(int);
71 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure, 65 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure,
72 &length, nullptr, 0); 66 &length, nullptr, 0);
73 return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); 67 return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
74 } 68 }
69 void MemoryPressureMonitor::OnMemoryPressureChanged(
70 dispatch_source_s* event_source,
71 const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
72 int mac_memory_pressure = dispatch_source_get_data(event_source);
73 MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
74 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
75 CFTimeInterval now = CFAbsoluteTimeGetCurrent();
76 CFTimeInterval since_last_change = now - last_pressure_change_;
77 last_pressure_change_ = now;
78
79 double ticks_to_report;
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;
94 if (memory_pressure_level !=
95 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
96 dispatch_callback.Run(memory_pressure_level);
97 }
75 98
76 void MemoryPressureMonitor::SetDispatchCallback( 99 void MemoryPressureMonitor::SetDispatchCallback(
77 const DispatchCallback& callback) { 100 const DispatchCallback& callback) {
78 dispatch_callback_ = callback; 101 dispatch_callback_ = callback;
79 } 102 }
80 103
81 } // namespace mac 104 } // namespace mac
82 } // namespace base 105 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/memory_pressure_monitor_mac.h ('k') | base/memory/memory_pressure_monitor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698