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

Side by Side Diff: base/chromeos/memory_pressure_monitor.cc

Issue 1124163003: Rename OS-specific MemoryPressureMonitor implementations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/chromeos/memory_pressure_monitor_chromeos.h" 5 #include "base/chromeos/memory_pressure_monitor.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/select.h> 8 #include <sys/select.h>
9 9
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/posix/eintr_wrapper.h" 11 #include "base/posix/eintr_wrapper.h"
12 #include "base/process/process_metrics.h" 12 #include "base/process/process_metrics.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 16
17 namespace base { 17 namespace base {
18 namespace chromeos {
18 19
19 namespace { 20 namespace {
20 21
21 // The time between memory pressure checks. While under critical pressure, this 22 // The time between memory pressure checks. While under critical pressure, this
22 // is also the timer to repeat cleanup attempts. 23 // is also the timer to repeat cleanup attempts.
23 const int kMemoryPressureIntervalMs = 1000; 24 const int kMemoryPressureIntervalMs = 1000;
24 25
25 // The time which should pass between two moderate memory pressure calls. 26 // The time which should pass between two moderate memory pressure calls.
26 const int kModerateMemoryPressureCooldownMs = 10000; 27 const int kModerateMemoryPressureCooldownMs = 10000;
27 28
(...skipping 18 matching lines...) Expand all
46 }; 47 };
47 48
48 // This is the file that will exist if low memory notification is available 49 // This is the file that will exist if low memory notification is available
49 // on the device. Whenever it becomes readable, it signals a low memory 50 // on the device. Whenever it becomes readable, it signals a low memory
50 // condition. 51 // condition.
51 const char kLowMemFile[] = "/dev/chromeos-low-mem"; 52 const char kLowMemFile[] = "/dev/chromeos-low-mem";
52 53
53 // Converts a |MemoryPressureThreshold| value into a used memory percentage for 54 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
54 // the moderate pressure event. 55 // the moderate pressure event.
55 int GetModerateMemoryThresholdInPercent( 56 int GetModerateMemoryThresholdInPercent(
56 MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) { 57 MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
57 return thresholds == MemoryPressureMonitorChromeOS:: 58 return thresholds == MemoryPressureMonitor::
58 THRESHOLD_AGGRESSIVE_CACHE_DISCARD || 59 THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
59 thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE 60 thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
60 ? kAggressiveMemoryPressureModerateThresholdPercent 61 ? kAggressiveMemoryPressureModerateThresholdPercent
61 : kNormalMemoryPressureModerateThresholdPercent; 62 : kNormalMemoryPressureModerateThresholdPercent;
62 } 63 }
63 64
64 // Converts a |MemoryPressureThreshold| value into a used memory percentage for 65 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
65 // the critical pressure event. 66 // the critical pressure event.
66 int GetCriticalMemoryThresholdInPercent( 67 int GetCriticalMemoryThresholdInPercent(
67 MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) { 68 MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
68 return thresholds == MemoryPressureMonitorChromeOS:: 69 return thresholds == MemoryPressureMonitor::
69 THRESHOLD_AGGRESSIVE_TAB_DISCARD || 70 THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
70 thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE 71 thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
71 ? kAggressiveMemoryPressureCriticalThresholdPercent 72 ? kAggressiveMemoryPressureCriticalThresholdPercent
72 : kNormalMemoryPressureCriticalThresholdPercent; 73 : kNormalMemoryPressureCriticalThresholdPercent;
73 } 74 }
74 75
75 // Converts free percent of memory into a memory pressure value. 76 // Converts free percent of memory into a memory pressure value.
76 MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel( 77 MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
77 int actual_fill_level, 78 int actual_fill_level,
78 int moderate_threshold, 79 int moderate_threshold,
79 int critical_threshold) { 80 int critical_threshold) {
80 if (actual_fill_level < moderate_threshold) 81 if (actual_fill_level < moderate_threshold)
(...skipping 13 matching lines...) Expand all
94 FD_SET(file_descriptor, &fds); 95 FD_SET(file_descriptor, &fds);
95 96
96 tv.tv_sec = 0; 97 tv.tv_sec = 0;
97 tv.tv_usec = 0; 98 tv.tv_usec = 0;
98 99
99 return HANDLE_EINTR(select(file_descriptor + 1, &fds, NULL, NULL, &tv)) > 0; 100 return HANDLE_EINTR(select(file_descriptor + 1, &fds, NULL, NULL, &tv)) > 0;
100 } 101 }
101 102
102 } // namespace 103 } // namespace
103 104
104 MemoryPressureMonitorChromeOS::MemoryPressureMonitorChromeOS( 105 MemoryPressureMonitor::MemoryPressureMonitor(
105 MemoryPressureThresholds thresholds) 106 MemoryPressureThresholds thresholds)
106 : current_memory_pressure_level_( 107 : current_memory_pressure_level_(
107 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), 108 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
108 moderate_pressure_repeat_count_(0), 109 moderate_pressure_repeat_count_(0),
109 moderate_pressure_threshold_percent_( 110 moderate_pressure_threshold_percent_(
110 GetModerateMemoryThresholdInPercent(thresholds)), 111 GetModerateMemoryThresholdInPercent(thresholds)),
111 critical_pressure_threshold_percent_( 112 critical_pressure_threshold_percent_(
112 GetCriticalMemoryThresholdInPercent(thresholds)), 113 GetCriticalMemoryThresholdInPercent(thresholds)),
113 low_mem_file_(HANDLE_EINTR(::open(kLowMemFile, O_RDONLY))), 114 low_mem_file_(HANDLE_EINTR(::open(kLowMemFile, O_RDONLY))),
114 weak_ptr_factory_(this) { 115 weak_ptr_factory_(this) {
115 StartObserving(); 116 StartObserving();
116 LOG_IF(ERROR, !low_mem_file_.is_valid()) << "Cannot open kernel listener"; 117 LOG_IF(ERROR, !low_mem_file_.is_valid()) << "Cannot open kernel listener";
117 } 118 }
118 119
119 MemoryPressureMonitorChromeOS::~MemoryPressureMonitorChromeOS() { 120 MemoryPressureMonitor::~MemoryPressureMonitor() {
120 StopObserving(); 121 StopObserving();
121 } 122 }
122 123
123 void MemoryPressureMonitorChromeOS::ScheduleEarlyCheck() { 124 void MemoryPressureMonitor::ScheduleEarlyCheck() {
124 ThreadTaskRunnerHandle::Get()->PostTask( 125 ThreadTaskRunnerHandle::Get()->PostTask(
125 FROM_HERE, Bind(&MemoryPressureMonitorChromeOS::CheckMemoryPressure, 126 FROM_HERE, Bind(&MemoryPressureMonitor::CheckMemoryPressure,
126 weak_ptr_factory_.GetWeakPtr())); 127 weak_ptr_factory_.GetWeakPtr()));
127 } 128 }
128 129
129 MemoryPressureListener::MemoryPressureLevel 130 MemoryPressureListener::MemoryPressureLevel
130 MemoryPressureMonitorChromeOS::GetCurrentPressureLevel() const { 131 MemoryPressureMonitor::GetCurrentPressureLevel() const {
131 return current_memory_pressure_level_; 132 return current_memory_pressure_level_;
132 } 133 }
133 134
134 void MemoryPressureMonitorChromeOS::StartObserving() { 135 void MemoryPressureMonitor::StartObserving() {
135 timer_.Start(FROM_HERE, 136 timer_.Start(FROM_HERE,
136 TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), 137 TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs),
137 Bind(&MemoryPressureMonitorChromeOS:: 138 Bind(&MemoryPressureMonitor::
138 CheckMemoryPressureAndRecordStatistics, 139 CheckMemoryPressureAndRecordStatistics,
139 weak_ptr_factory_.GetWeakPtr())); 140 weak_ptr_factory_.GetWeakPtr()));
140 } 141 }
141 142
142 void MemoryPressureMonitorChromeOS::StopObserving() { 143 void MemoryPressureMonitor::StopObserving() {
143 // If StartObserving failed, StopObserving will still get called. 144 // If StartObserving failed, StopObserving will still get called.
144 timer_.Stop(); 145 timer_.Stop();
145 } 146 }
146 147
147 void MemoryPressureMonitorChromeOS::CheckMemoryPressureAndRecordStatistics() { 148 void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
148 CheckMemoryPressure(); 149 CheckMemoryPressure();
149 150
150 // Record UMA histogram statistics for the current memory pressure level. 151 // Record UMA histogram statistics for the current memory pressure level.
151 MemoryPressureLevelUMA memory_pressure_level_uma(MEMORY_PRESSURE_LEVEL_NONE); 152 MemoryPressureLevelUMA memory_pressure_level_uma(MEMORY_PRESSURE_LEVEL_NONE);
152 switch (current_memory_pressure_level_) { 153 switch (current_memory_pressure_level_) {
153 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: 154 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
154 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_NONE; 155 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_NONE;
155 break; 156 break;
156 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: 157 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
157 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_MODERATE; 158 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_MODERATE;
158 break; 159 break;
159 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: 160 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
160 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_CRITICAL; 161 memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_CRITICAL;
161 break; 162 break;
162 } 163 }
163 164
164 UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel", 165 UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel",
165 memory_pressure_level_uma, 166 memory_pressure_level_uma,
166 NUM_MEMORY_PRESSURE_LEVELS); 167 NUM_MEMORY_PRESSURE_LEVELS);
167 } 168 }
168 169
169 void MemoryPressureMonitorChromeOS::CheckMemoryPressure() { 170 void MemoryPressureMonitor::CheckMemoryPressure() {
170 MemoryPressureListener::MemoryPressureLevel old_pressure = 171 MemoryPressureListener::MemoryPressureLevel old_pressure =
171 current_memory_pressure_level_; 172 current_memory_pressure_level_;
172 173
173 // If we have the kernel low memory observer, we use it's flag instead of our 174 // If we have the kernel low memory observer, we use it's flag instead of our
174 // own computation (for now). Note that in "simulation mode" it can be null. 175 // own computation (for now). Note that in "simulation mode" it can be null.
175 // TODO(skuhne): We need to add code which makes sure that the kernel and this 176 // TODO(skuhne): We need to add code which makes sure that the kernel and this
176 // computation come to similar results and then remove this override again. 177 // computation come to similar results and then remove this override again.
177 // TODO(skuhne): Add some testing framework here to see how close the kernel 178 // TODO(skuhne): Add some testing framework here to see how close the kernel
178 // and the internal functions are. 179 // and the internal functions are.
179 if (low_mem_file_.is_valid() && IsLowMemoryCondition(low_mem_file_.get())) { 180 if (low_mem_file_.is_valid() && IsLowMemoryCondition(low_mem_file_.get())) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // When we reducing the pressure level from critical to moderate, we 218 // When we reducing the pressure level from critical to moderate, we
218 // restart the timeout and do not send another notification. 219 // restart the timeout and do not send another notification.
219 moderate_pressure_repeat_count_ = 0; 220 moderate_pressure_repeat_count_ = 0;
220 return; 221 return;
221 } 222 }
222 moderate_pressure_repeat_count_ = 0; 223 moderate_pressure_repeat_count_ = 0;
223 MemoryPressureListener::NotifyMemoryPressure(current_memory_pressure_level_); 224 MemoryPressureListener::NotifyMemoryPressure(current_memory_pressure_level_);
224 } 225 }
225 226
226 // Gets the used ChromeOS memory in percent. 227 // Gets the used ChromeOS memory in percent.
227 int MemoryPressureMonitorChromeOS::GetUsedMemoryInPercent() { 228 int MemoryPressureMonitor::GetUsedMemoryInPercent() {
228 base::SystemMemoryInfoKB info; 229 base::SystemMemoryInfoKB info;
229 if (!base::GetSystemMemoryInfo(&info)) { 230 if (!base::GetSystemMemoryInfo(&info)) {
230 VLOG(1) << "Cannot determine the free memory of the system."; 231 VLOG(1) << "Cannot determine the free memory of the system.";
231 return 0; 232 return 0;
232 } 233 }
233 // TODO(skuhne): Instead of adding the kernel memory pressure calculation 234 // TODO(skuhne): Instead of adding the kernel memory pressure calculation
234 // logic here, we should have a kernel mechanism similar to the low memory 235 // logic here, we should have a kernel mechanism similar to the low memory
235 // notifier in ChromeOS which offers multiple pressure states. 236 // notifier in ChromeOS which offers multiple pressure states.
236 // To track this, we have crbug.com/381196. 237 // To track this, we have crbug.com/381196.
237 238
(...skipping 16 matching lines...) Expand all
254 255
255 // Available memory is the sum of free, swap and easy reclaimable memory. 256 // Available memory is the sum of free, swap and easy reclaimable memory.
256 int available_memory = 257 int available_memory =
257 info.free + info.swap_free / kSwapWeight + file_memory; 258 info.free + info.swap_free / kSwapWeight + file_memory;
258 259
259 DCHECK(available_memory < total_memory); 260 DCHECK(available_memory < total_memory);
260 int percentage = ((total_memory - available_memory) * 100) / total_memory; 261 int percentage = ((total_memory - available_memory) * 100) / total_memory;
261 return percentage; 262 return percentage;
262 } 263 }
263 264
265 } // namespace chromeos
264 } // namespace base 266 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698