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 <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include "base/macros.h" | |
11 #include "base/metrics/histogram_macros.h" | |
12 #include "base/time/tick_clock.h" | |
13 | |
14 namespace memory_pressure { | |
15 | |
16 namespace { | |
17 | |
18 using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel; | |
19 | |
20 // Converts a memory pressure level to an UMA enumeration value. | |
21 MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue( | |
22 MemoryPressureLevel level) { | |
23 switch (level) { | |
24 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: | |
25 return UMA_MEMORY_PRESSURE_LEVEL_NONE; | |
26 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: | |
27 return UMA_MEMORY_PRESSURE_LEVEL_MODERATE; | |
28 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: | |
29 return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL; | |
30 } | |
31 NOTREACHED(); | |
32 return UMA_MEMORY_PRESSURE_LEVEL_NONE; | |
33 } | |
34 | |
35 // Converts an UMA enumeration value to a memory pressure level. | |
36 MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue( | |
37 MemoryPressureLevelUMA level) { | |
38 switch (level) { | |
39 case UMA_MEMORY_PRESSURE_LEVEL_NONE: | |
40 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; | |
41 case UMA_MEMORY_PRESSURE_LEVEL_MODERATE: | |
42 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE; | |
43 case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL: | |
44 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; | |
45 case UMA_MEMORY_PRESSURE_LEVEL_COUNT: | |
46 NOTREACHED(); | |
47 break; | |
48 } | |
49 NOTREACHED(); | |
50 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; | |
51 } | |
52 | |
53 } // namespace | |
54 | |
55 MemoryPressureStatsCollector::MemoryPressureStatsCollector( | |
56 base::TickClock* tick_clock) | |
57 : tick_clock_(tick_clock), | |
58 last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { | |
59 } | |
60 | |
61 void MemoryPressureStatsCollector::UpdateStatistics( | |
62 MemoryPressureLevel current_pressure_level) { | |
63 base::TimeTicks now = tick_clock_->NowTicks(); | |
64 | |
65 // Special case: first call to the collector. Observations have just started | |
66 // so there's nothing to report. | |
67 if (last_update_time_.is_null()) { | |
68 last_pressure_level_ = current_pressure_level; | |
69 last_update_time_ = now; | |
70 return; | |
71 } | |
72 | |
73 // If the pressure level has transitioned then report this. | |
74 if (last_pressure_level_ != current_pressure_level) | |
75 ReportLevelChange(last_pressure_level_, current_pressure_level); | |
76 | |
77 // Increment the appropriate cumulative bucket. | |
78 int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level); | |
79 unreported_cumulative_time_[index] += now - last_update_time_; | |
80 | |
81 // Update last pressure related state. | |
82 last_pressure_level_ = current_pressure_level; | |
83 last_update_time_ = now; | |
84 | |
85 // Make reports about the amount of time spent cumulatively at each level. | |
86 for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) { | |
87 // Report the largest number of whole seconds possible at this moment and | |
88 // carry around the rest for a future report. | |
89 if (unreported_cumulative_time_[i].is_zero()) | |
90 continue; | |
91 int64_t seconds = unreported_cumulative_time_[i].InSeconds(); | |
92 if (seconds == 0) | |
93 continue; | |
94 unreported_cumulative_time_[i] -= base::TimeDelta::FromSeconds(seconds); | |
95 | |
96 ReportCumulativeTime(MemoryPressureLevelFromUmaEnumValue( | |
97 static_cast<MemoryPressureLevelUMA>(i)), | |
98 static_cast<int>(seconds)); | |
99 } | |
100 } | |
101 | |
102 // static | |
103 void MemoryPressureStatsCollector::ReportCumulativeTime( | |
104 MemoryPressureLevel pressure_level, | |
105 int seconds) { | |
106 // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the | |
107 // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality. | |
108 STATIC_HISTOGRAM_POINTER_BLOCK( | |
109 "Memory.PressureLevel", | |
110 AddCount(MemoryPressureLevelToUmaEnumValue(pressure_level), seconds), | |
111 base::LinearHistogram::FactoryGet( | |
112 "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT, | |
113 UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1, | |
114 base::HistogramBase::kUmaTargetedHistogramFlag)); | |
115 } | |
116 | |
117 // static | |
118 void MemoryPressureStatsCollector::ReportLevelChange( | |
119 MemoryPressureLevel old_pressure_level, | |
120 MemoryPressureLevel new_pressure_level) { | |
121 // TODO(chrisha): Report Memory.PressureLevelChange when this code is in use. | |
122 } | |
123 | |
124 } // namespace memory_pressure | |
OLD | NEW |