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
3 // found in the LICENSE file.
4 
5 #include "base/memory/memory_pressure_monitor.h"
6 
7 #include "base/logging.h"
8 #include "base/metrics/histogram_macros.h"
9 
10 namespace base {
11 namespace {
12 
13 MemoryPressureMonitor* g_monitor = nullptr;
14 
15 // Enumeration of UMA memory pressure levels. This needs to be kept in sync with
16 // histograms.xml and the memory pressure levels defined in
17 // MemoryPressureListener.
18 enum MemoryPressureLevelUMA {
19   UMA_MEMORY_PRESSURE_LEVEL_NONE = 0,
20   UMA_MEMORY_PRESSURE_LEVEL_MODERATE = 1,
21   UMA_MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
22   // This must be the last value in the enum.
23   UMA_MEMORY_PRESSURE_LEVEL_COUNT,
24 };
25 
26 // Converts a memory pressure level to an UMA enumeration value.
MemoryPressureLevelToUmaEnumValue(base::MemoryPressureListener::MemoryPressureLevel level)27 MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
28     base::MemoryPressureListener::MemoryPressureLevel level) {
29   switch (level) {
30     case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
31       return UMA_MEMORY_PRESSURE_LEVEL_NONE;
32     case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
33       return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
34     case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
35       return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
36   }
37   NOTREACHED();
38   return UMA_MEMORY_PRESSURE_LEVEL_NONE;
39 }
40 
41 }  // namespace
42 
43 const base::TimeDelta MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod =
44     base::TimeDelta::FromSeconds(5);
45 
MemoryPressureMonitor()46 MemoryPressureMonitor::MemoryPressureMonitor() {
47   DCHECK(!g_monitor);
48   g_monitor = this;
49 }
50 
~MemoryPressureMonitor()51 MemoryPressureMonitor::~MemoryPressureMonitor() {
52   DCHECK(g_monitor);
53   g_monitor = nullptr;
54 }
55 
56 // static
Get()57 MemoryPressureMonitor* MemoryPressureMonitor::Get() {
58   return g_monitor;
59 }
RecordMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel level,int ticks)60 void MemoryPressureMonitor::RecordMemoryPressure(
61     base::MemoryPressureListener::MemoryPressureLevel level,
62     int ticks) {
63   // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
64   // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality.
65   STATIC_HISTOGRAM_POINTER_BLOCK(
66       "Memory.PressureLevel",
67       AddCount(MemoryPressureLevelToUmaEnumValue(level), ticks),
68       base::LinearHistogram::FactoryGet(
69           "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT,
70           UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1,
71           base::HistogramBase::kUmaTargetedHistogramFlag));
72 }
73 
74 }  // namespace base
75