OLD | NEW |
---|---|
(Empty) | |
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 "components/memory_pressure/memory_pressure_stats_collector.h" | |
6 | |
7 #include "base/metrics/histogram.h" | |
8 #include "base/time/default_tick_clock.h" | |
9 | |
10 namespace memory_pressure { | |
11 | |
12 namespace { | |
13 | |
14 using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel; | |
15 | |
16 // A special memory pressure level that is used to indicate that the stats | |
17 // collector has not yet been called. | |
18 const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_INVALID = | |
19 static_cast<MemoryPressureLevel>( | |
20 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE - 1); | |
21 | |
22 // Converts a memory pressure level to an UMA enumeration value. | |
23 MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue( | |
24 MemoryPressureLevel level) { | |
25 switch (level) { | |
26 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: | |
27 return UMA_MEMORY_PRESSURE_LEVEL_NONE; | |
28 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: | |
29 return UMA_MEMORY_PRESSURE_LEVEL_MODERATE; | |
30 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: | |
31 return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL; | |
32 } | |
33 NOTREACHED(); | |
34 return UMA_MEMORY_PRESSURE_LEVEL_COUNT; | |
35 } | |
36 | |
37 // Converts an UMA enumeration value to a memory pressure level. | |
38 MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue( | |
39 MemoryPressureLevelUMA level) { | |
40 switch (level) { | |
41 case UMA_MEMORY_PRESSURE_LEVEL_NONE: | |
42 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; | |
43 case UMA_MEMORY_PRESSURE_LEVEL_MODERATE: | |
44 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE; | |
45 case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL: | |
46 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; | |
47 } | |
48 NOTREACHED(); | |
49 return MEMORY_PRESSURE_LEVEL_INVALID; | |
50 } | |
51 | |
52 } // namespace | |
53 | |
54 MemoryPressureStatsCollector::MemoryPressureStatsCollector() | |
55 : reporting_delegate_(new UmaReportingDelegate()), | |
56 tick_clock_(new base::DefaultTickClock()), | |
57 last_pressure_level_(MEMORY_PRESSURE_LEVEL_INVALID) {} | |
58 | |
59 void MemoryPressureStatsCollector::UpdateStatistics( | |
60 MemoryPressureLevel current_pressure_level) { | |
61 base::TimeTicks now = tick_clock_->NowTicks(); | |
62 | |
63 // Special case: first call to the collector. Observations have just started | |
64 // so there's nothing to report. | |
65 if (last_pressure_level_ == MEMORY_PRESSURE_LEVEL_INVALID) { | |
66 last_pressure_level_ = current_pressure_level; | |
67 last_update_time_ = now; | |
68 return; | |
69 } | |
70 | |
71 // If the pressure level has transitioned then report this. | |
72 if (last_pressure_level_ != current_pressure_level) { | |
73 reporting_delegate_->ReportLevelChange(last_pressure_level_, | |
74 current_pressure_level); | |
75 } | |
76 | |
77 // Increment the appropriate cumulative bucket. | |
78 int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level); | |
79 base::TimeDelta time_since_update = now - last_update_time_; | |
80 unreported_cumulative_time_[index] += time_since_update; | |
81 | |
82 // Update last pressure related state. | |
83 last_pressure_level_ = current_pressure_level; | |
84 last_update_time_ = now; | |
85 | |
86 // Make reports about the amount of time spent cumulatively at each level. | |
87 for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) { | |
88 if (unreported_cumulative_time_[i].is_zero()) | |
89 continue; | |
90 reporting_delegate_->ReportCumulativeTime( | |
91 MemoryPressureLevelFromUmaEnumValue( | |
92 static_cast<MemoryPressureLevelUMA>(i)), | |
93 &unreported_cumulative_time_[i]); | |
94 } | |
95 } | |
96 | |
97 namespace { | |
98 | |
99 // Enumeration of UMA pressure level changes. This needs to be kept in sync | |
100 // with histograms.xml and the memory pressure levels defined in | |
101 // MemoryPressureListener. | |
102 enum MemoryPressureLevelChangeUMA { | |
103 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE = 0, | |
104 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL = 1, | |
105 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL = 2, | |
106 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE = 3, | |
107 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_NONE = 4, | |
108 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE = 5, | |
109 // This must be the last value in the enum. | |
110 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT | |
111 }; | |
112 | |
113 // Converts a pressure state change to an UMA enumeration value. | |
114 MemoryPressureLevelChangeUMA MemoryPressureLevelChangeToUmaEnumValue( | |
115 MemoryPressureLevel old_level, | |
116 MemoryPressureLevel new_level) { | |
117 switch (old_level) { | |
118 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: { | |
119 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) | |
120 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE; | |
121 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) | |
122 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL; | |
123 } | |
124 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: { | |
125 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) | |
126 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE; | |
127 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) | |
128 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL; | |
129 } | |
130 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: { | |
131 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) | |
132 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE; | |
133 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) | |
134 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE; | |
135 } | |
136 } | |
137 NOTREACHED(); | |
138 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT; | |
139 } | |
140 | |
141 } // namespace | |
142 | |
143 void MemoryPressureStatsCollector::UmaReportingDelegate::ReportCumulativeTime( | |
144 MemoryPressureLevel pressure_level, | |
145 base::TimeDelta* time) { | |
146 // Extract the number of seconds and leave behind the milliseconds. | |
147 int64 seconds = time->InSeconds(); | |
148 *time -= base::TimeDelta::FromSeconds(seconds); | |
149 | |
150 // Increment the histogram for each second spent in the given state. | |
151 for (int64 i = 0; i < seconds; ++i) { | |
152 UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevel", | |
rkaplow
2015/09/03 17:22:36
alexei - is there a more efficient way to add N en
rkaplow
2015/09/03 17:22:36
We're already writing to this in other places eg.
chrisha
2015/09/03 20:00:45
Turns out there is now! AddCount! But it's not exp
chrisha
2015/09/03 20:00:45
No interaction at all. This component will replace
rkaplow
2015/09/03 22:15:07
Agreed. This is fine for now. Maybe add a TODO to
rkaplow
2015/09/03 22:15:07
AH right - missed that this wasn't hooked up yet.
| |
153 MemoryPressureLevelToUmaEnumValue(pressure_level), | |
154 UMA_MEMORY_PRESSURE_LEVEL_COUNT); | |
155 #if defined(OS_CHROMEOS) | |
156 // Continue to emit the old metric on ChromeOS during the transition period. | |
rkaplow
2015/09/03 17:22:36
describe a little more maybe how this is transitio
chrisha
2015/09/03 20:00:45
Actually, I've rethought this. When I switch to us
rkaplow
2015/09/03 22:15:07
that sounds good.
| |
157 UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel", | |
158 MemoryPressureLevelToUmaEnumValue(pressure_level), | |
159 UMA_MEMORY_PRESSURE_LEVEL_COUNT); | |
160 #endif | |
161 } | |
162 } | |
163 | |
164 void MemoryPressureStatsCollector::UmaReportingDelegate::ReportLevelChange( | |
165 MemoryPressureLevel old_pressure_level, | |
166 MemoryPressureLevel new_pressure_level) { | |
167 UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevelChange", | |
168 MemoryPressureLevelChangeToUmaEnumValue( | |
169 old_pressure_level, new_pressure_level), | |
170 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT); | |
171 } | |
172 | |
173 } // namespace memory_pressure | |
OLD | NEW |