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

Side by Side Diff: components/memory_pressure/memory_pressure_stats_collector.cc

Issue 1310043004: Create MemoryPressureStatsCollector. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed rkaplow's comments. Created 5 years, 3 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
(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
9 namespace memory_pressure {
10
11 namespace {
12
13 using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
14
15 // A special memory pressure level that is used to indicate that the stats
16 // collector has not yet been called.
17 const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_INVALID =
18 static_cast<MemoryPressureLevel>(
19 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE - 1);
20
21 // Converts a memory pressure level to an UMA enumeration value.
22 MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
23 MemoryPressureLevel level) {
24 switch (level) {
25 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
26 return UMA_MEMORY_PRESSURE_LEVEL_NONE;
27 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
28 return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
29 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
30 return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
31 }
32 NOTREACHED();
33 return UMA_MEMORY_PRESSURE_LEVEL_COUNT;
grt (UTC plus 2) 2015/09/08 17:22:46 this will lead to an out-of-bounds write on line 7
chrisha 2015/09/08 18:48:42 This is just to keep the compiler happy (MSVS PGO
34 }
35
36 // Converts an UMA enumeration value to a memory pressure level.
37 MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue(
38 MemoryPressureLevelUMA level) {
39 switch (level) {
40 case UMA_MEMORY_PRESSURE_LEVEL_NONE:
41 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
42 case UMA_MEMORY_PRESSURE_LEVEL_MODERATE:
43 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
44 case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL:
45 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
46 }
grt (UTC plus 2) 2015/09/08 17:22:46 case UMA_MEMORY_PRESSURE_LEVEL_COUNT: NOTREA
chrisha 2015/09/08 18:48:43 Done.
47 NOTREACHED();
48 return MEMORY_PRESSURE_LEVEL_INVALID;
grt (UTC plus 2) 2015/09/08 17:22:46 returning something that isn't a real MemoryPressu
chrisha 2015/09/08 18:48:42 Same comment as above. It will never actually run,
49 }
50
51 } // namespace
52
53 MemoryPressureStatsCollector::MemoryPressureStatsCollector(
54 base::TickClock* tick_clock)
55 : tick_clock_(tick_clock),
56 last_pressure_level_(MEMORY_PRESSURE_LEVEL_INVALID) {}
57
58 void MemoryPressureStatsCollector::UpdateStatistics(
59 MemoryPressureLevel current_pressure_level) {
60 base::TimeTicks now = tick_clock_->NowTicks();
61
62 // Special case: first call to the collector. Observations have just started
63 // so there's nothing to report.
64 if (last_pressure_level_ == MEMORY_PRESSURE_LEVEL_INVALID) {
grt (UTC plus 2) 2015/09/08 17:22:46 can you do away with the MEMORY_PRESSURE_LEVEL_INV
chrisha 2015/09/08 18:48:43 sgtm. Done.
65 last_pressure_level_ = current_pressure_level;
66 last_update_time_ = now;
67 return;
68 }
69
70 // If the pressure level has transitioned then report this.
71 if (last_pressure_level_ != current_pressure_level)
72 ReportLevelChange(last_pressure_level_, current_pressure_level);
73
74 // Increment the appropriate cumulative bucket.
75 int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level);
76 base::TimeDelta time_since_update = now - last_update_time_;
grt (UTC plus 2) 2015/09/08 17:22:46 nit: inline the delta computation on the line belo
chrisha 2015/09/08 18:48:43 Done.
77 unreported_cumulative_time_[index] += time_since_update;
78
79 // Update last pressure related state.
80 last_pressure_level_ = current_pressure_level;
81 last_update_time_ = now;
82
83 // Make reports about the amount of time spent cumulatively at each level.
84 for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) {
85 // Report the largest number of whole seconds possible at this moment and
86 // carry around the rest for a future report.
87 if (unreported_cumulative_time_[i].is_zero())
88 continue;
89 int64_t seconds = unreported_cumulative_time_[i].InSeconds();
90 if (seconds == 0)
91 continue;
92 unreported_cumulative_time_[i] -= base::TimeDelta::FromSeconds(seconds);
93
94 ReportCumulativeTime(MemoryPressureLevelFromUmaEnumValue(
95 static_cast<MemoryPressureLevelUMA>(i)),
96 static_cast<int>(seconds));
97 }
98 }
99
100 namespace {
101
102 // Converts a pressure state change to an UMA enumeration value.
grt (UTC plus 2) 2015/09/08 17:22:46 optional nit: move this into the unnamed namespace
chrisha 2015/09/08 18:48:43 I tend to prefer having private implementation det
103 MemoryPressureLevelChangeUMA MemoryPressureLevelChangeToUmaEnumValue(
104 MemoryPressureLevel old_level,
105 MemoryPressureLevel new_level) {
106 switch (old_level) {
107 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: {
108 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
109 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE;
110 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
grt (UTC plus 2) 2015/09/08 17:22:46 each of these will silently fall through if a new
chrisha 2015/09/08 18:48:43 I've gone with the break, as this is a case of "sh
111 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL;
112 }
113 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: {
114 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
115 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE;
116 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
117 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL;
118 }
119 case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: {
120 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
121 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
122 if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
123 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
124 }
125 }
grt (UTC plus 2) 2015/09/08 17:22:46 add a case for UMA_MEMORY_PRESSURE_LEVEL_COUNT tha
chrisha 2015/09/08 18:48:43 This switches off the MemoryPressureListern enum,
grt (UTC plus 2) 2015/09/08 19:22:10 oh yeah, duh.
chrisha 2015/09/08 19:57:53 Acknowledged.
126 NOTREACHED();
127 return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT;
128 }
129
130 } // namespace
131
132 // static
133 void MemoryPressureStatsCollector::ReportCumulativeTime(
134 MemoryPressureLevel pressure_level,
135 int seconds) {
136 // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
137 // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality.
138 STATIC_HISTOGRAM_POINTER_BLOCK(
139 "Memory.PressureLevel",
140 AddCount(MemoryPressureLevelToUmaEnumValue(pressure_level), seconds),
141 base::LinearHistogram::FactoryGet(
142 "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT,
143 UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1,
144 base::HistogramBase::kUmaTargetedHistogramFlag));
145 }
146
147 // static
148 void MemoryPressureStatsCollector::ReportLevelChange(
149 MemoryPressureLevel old_pressure_level,
150 MemoryPressureLevel new_pressure_level) {
151 UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevelChange",
152 MemoryPressureLevelChangeToUmaEnumValue(
153 old_pressure_level, new_pressure_level),
154 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT);
155 }
156
157 } // namespace memory_pressure
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698