Roll src/third_party/WebKit 9f7fb92:f103b33 (svn 202621:202622)
[chromium-blink-merge.git] / components / memory_pressure / memory_pressure_stats_collector.cc
blobacafd0cab3bc868738fb033d6d5a0fd9daeec626
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.
5 #include "components/memory_pressure/memory_pressure_stats_collector.h"
7 #include "base/metrics/histogram.h"
8 #include "base/time/tick_clock.h"
10 namespace memory_pressure {
12 namespace {
14 using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
16 // Converts a memory pressure level to an UMA enumeration value.
17 MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
18 MemoryPressureLevel level) {
19 switch (level) {
20 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
21 return UMA_MEMORY_PRESSURE_LEVEL_NONE;
22 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
23 return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
24 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
25 return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
27 NOTREACHED();
28 return UMA_MEMORY_PRESSURE_LEVEL_NONE;
31 // Converts an UMA enumeration value to a memory pressure level.
32 MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue(
33 MemoryPressureLevelUMA level) {
34 switch (level) {
35 case UMA_MEMORY_PRESSURE_LEVEL_NONE:
36 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
37 case UMA_MEMORY_PRESSURE_LEVEL_MODERATE:
38 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
39 case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL:
40 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
41 case UMA_MEMORY_PRESSURE_LEVEL_COUNT:
42 NOTREACHED();
43 break;
45 NOTREACHED();
46 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
49 // Converts a pressure state change to an UMA enumeration value.
50 MemoryPressureLevelChangeUMA MemoryPressureLevelChangeToUmaEnumValue(
51 MemoryPressureLevel old_level,
52 MemoryPressureLevel new_level) {
53 switch (old_level) {
54 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: {
55 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
56 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE;
57 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
58 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL;
59 break; // Should never happen; handled by the NOTREACHED below.
61 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: {
62 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
63 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE;
64 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
65 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL;
66 break; // Should never happen; handled by the NOTREACHED below.
68 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: {
69 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
70 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
71 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
72 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
73 break; // Should never happen; handled by the NOTREACHED below.
76 NOTREACHED();
77 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE;
80 } // namespace
82 MemoryPressureStatsCollector::MemoryPressureStatsCollector(
83 base::TickClock* tick_clock)
84 : tick_clock_(tick_clock),
85 last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
88 void MemoryPressureStatsCollector::UpdateStatistics(
89 MemoryPressureLevel current_pressure_level) {
90 base::TimeTicks now = tick_clock_->NowTicks();
92 // Special case: first call to the collector. Observations have just started
93 // so there's nothing to report.
94 if (last_update_time_.is_null()) {
95 last_pressure_level_ = current_pressure_level;
96 last_update_time_ = now;
97 return;
100 // If the pressure level has transitioned then report this.
101 if (last_pressure_level_ != current_pressure_level)
102 ReportLevelChange(last_pressure_level_, current_pressure_level);
104 // Increment the appropriate cumulative bucket.
105 int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level);
106 unreported_cumulative_time_[index] += now - last_update_time_;
108 // Update last pressure related state.
109 last_pressure_level_ = current_pressure_level;
110 last_update_time_ = now;
112 // Make reports about the amount of time spent cumulatively at each level.
113 for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) {
114 // Report the largest number of whole seconds possible at this moment and
115 // carry around the rest for a future report.
116 if (unreported_cumulative_time_[i].is_zero())
117 continue;
118 int64_t seconds = unreported_cumulative_time_[i].InSeconds();
119 if (seconds == 0)
120 continue;
121 unreported_cumulative_time_[i] -= base::TimeDelta::FromSeconds(seconds);
123 ReportCumulativeTime(MemoryPressureLevelFromUmaEnumValue(
124 static_cast<MemoryPressureLevelUMA>(i)),
125 static_cast<int>(seconds));
129 // static
130 void MemoryPressureStatsCollector::ReportCumulativeTime(
131 MemoryPressureLevel pressure_level,
132 int seconds) {
133 // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
134 // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality.
135 STATIC_HISTOGRAM_POINTER_BLOCK(
136 "Memory.PressureLevel",
137 AddCount(MemoryPressureLevelToUmaEnumValue(pressure_level), seconds),
138 base::LinearHistogram::FactoryGet(
139 "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT,
140 UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1,
141 base::HistogramBase::kUmaTargetedHistogramFlag));
144 // static
145 void MemoryPressureStatsCollector::ReportLevelChange(
146 MemoryPressureLevel old_pressure_level,
147 MemoryPressureLevel new_pressure_level) {
148 UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevelChange",
149 MemoryPressureLevelChangeToUmaEnumValue(
150 old_pressure_level, new_pressure_level),
151 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT);
154 } // namespace memory_pressure