ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / performance_monitor / process_metrics_history.cc
blob824444b67f9d7c4b47c32f3cf6539710fc5e14ec
1 // Copyright 2013 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 "chrome/browser/performance_monitor/process_metrics_history.h"
7 #include <limits>
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/process/process_metrics.h"
12 #include "content/public/common/process_type.h"
14 #if defined(OS_MACOSX)
15 #include "content/public/browser/browser_child_process_host.h"
16 #endif
18 namespace performance_monitor {
20 namespace {
22 const char kBrowserProcessTrigger[] =
23 "ProcessMetricsHistory.BrowserProcess.HighCPU";
24 const char kGPUProcessTrigger[] = "ProcessMetricsHistory.GPUProcess.HighCPU";
25 const char kExtensionPersistentProcessTrigger[] =
26 "ProcessMetricsHistory.ExtensionPersistentProcess.HighCPU";
28 } // namespace
30 // If a process is consistently above this CPU utilization percentage over time,
31 // we consider it as high and may take action.
32 const float kHighCPUUtilizationThreshold = 90.0f;
34 ProcessMetricsHistory::ProcessMetricsHistory()
35 : last_update_sequence_(0), cpu_usage_(0.0), trace_trigger_handle_(-1) {
38 ProcessMetricsHistory::~ProcessMetricsHistory() {
41 void ProcessMetricsHistory::Initialize(
42 const ProcessMetricsMetadata& process_data,
43 int initial_update_sequence) {
44 DCHECK_EQ(base::kNullProcessHandle, process_data_.handle);
45 process_data_ = process_data;
46 last_update_sequence_ = initial_update_sequence;
48 #if defined(OS_MACOSX)
49 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(
50 process_data_.handle,
51 content::BrowserChildProcessHost::GetPortProvider()));
52 #else
53 process_metrics_.reset(
54 base::ProcessMetrics::CreateProcessMetrics(process_data_.handle));
55 #endif
57 const char* trigger_name = NULL;
58 switch (process_data_.process_type) {
59 case content::PROCESS_TYPE_BROWSER:
60 trigger_name = kBrowserProcessTrigger;
61 break;
62 case content::PROCESS_TYPE_GPU:
63 trigger_name = kGPUProcessTrigger;
64 break;
66 switch (process_data_.process_subtype) {
67 case kProcessSubtypeExtensionPersistent:
68 trigger_name = kExtensionPersistentProcessTrigger;
69 break;
70 default:
71 break;
73 if (trigger_name) {
74 trace_trigger_handle_ =
75 content::BackgroundTracingManager::GetInstance()->RegisterTriggerType(
76 trigger_name);
80 void ProcessMetricsHistory::SampleMetrics() {
81 cpu_usage_ = process_metrics_->GetPlatformIndependentCPUUsage();
84 void ProcessMetricsHistory::RunPerformanceTriggers() {
85 // We scale up to the equivalent of 64 CPU cores fully loaded. More than this
86 // doesn't really matter, as we're already in a terrible place.
87 const int kHistogramMin = 0;
88 const int kHistogramMax = 6400;
89 const int kHistogramBucketCount = 50;
91 // The histogram macros don't support variables as histogram names,
92 // hence the macro duplication for each process type.
93 switch (process_data_.process_type) {
94 case content::PROCESS_TYPE_BROWSER:
95 UMA_HISTOGRAM_CUSTOM_COUNTS(
96 "PerformanceMonitor.AverageCPU.BrowserProcess", cpu_usage_,
97 kHistogramMin, kHistogramMax, kHistogramBucketCount);
98 // If CPU usage has consistently been above our threshold,
99 // we *may* have an issue.
100 if (cpu_usage_ > kHighCPUUtilizationThreshold) {
101 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.BrowserProcess",
102 true);
104 break;
105 case content::PROCESS_TYPE_RENDERER:
106 UMA_HISTOGRAM_CUSTOM_COUNTS(
107 "PerformanceMonitor.AverageCPU.RendererProcess", cpu_usage_,
108 kHistogramMin, kHistogramMax, kHistogramBucketCount);
109 if (cpu_usage_ > kHighCPUUtilizationThreshold) {
110 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.RendererProcess",
111 true);
113 break;
114 case content::PROCESS_TYPE_PLUGIN:
115 UMA_HISTOGRAM_CUSTOM_COUNTS("PerformanceMonitor.AverageCPU.PluginProcess",
116 cpu_usage_, kHistogramMin, kHistogramMax,
117 kHistogramBucketCount);
118 if (cpu_usage_ > kHighCPUUtilizationThreshold)
119 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.PluginProcess", true);
120 break;
121 case content::PROCESS_TYPE_GPU:
122 UMA_HISTOGRAM_CUSTOM_COUNTS("PerformanceMonitor.AverageCPU.GPUProcess",
123 cpu_usage_, kHistogramMin, kHistogramMax,
124 kHistogramBucketCount);
125 if (cpu_usage_ > kHighCPUUtilizationThreshold)
126 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.GPUProcess", true);
127 break;
128 case content::PROCESS_TYPE_PPAPI_PLUGIN:
129 UMA_HISTOGRAM_CUSTOM_COUNTS("PerformanceMonitor.AverageCPU.PPAPIProcess",
130 cpu_usage_, kHistogramMin, kHistogramMax,
131 kHistogramBucketCount);
132 if (cpu_usage_ > kHighCPUUtilizationThreshold)
133 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.PPAPIProcess", true);
134 break;
135 default:
136 break;
139 switch (process_data_.process_subtype) {
140 case kProcessSubtypeUnknown:
141 break;
142 case kProcessSubtypePPAPIFlash:
143 UMA_HISTOGRAM_CUSTOM_COUNTS(
144 "PerformanceMonitor.AverageCPU.PPAPIFlashProcess", cpu_usage_,
145 kHistogramMin, kHistogramMax, kHistogramBucketCount);
146 if (cpu_usage_ > kHighCPUUtilizationThreshold) {
147 UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.PPAPIFlashProcess",
148 true);
150 break;
151 case kProcessSubtypeExtensionPersistent:
152 UMA_HISTOGRAM_CUSTOM_COUNTS(
153 "PerformanceMonitor.AverageCPU.RendererExtensionPersistentProcess",
154 cpu_usage_, kHistogramMin, kHistogramMax, kHistogramBucketCount);
155 if (cpu_usage_ > kHighCPUUtilizationThreshold) {
156 UMA_HISTOGRAM_BOOLEAN(
157 "PerformanceMonitor.HighCPU.RendererExtensionPersistentProcess",
158 true);
160 break;
161 case kProcessSubtypeExtensionEvent:
162 UMA_HISTOGRAM_CUSTOM_COUNTS(
163 "PerformanceMonitor.AverageCPU.RendererExtensionEventProcess",
164 cpu_usage_, kHistogramMin, kHistogramMax, kHistogramBucketCount);
165 if (cpu_usage_ > kHighCPUUtilizationThreshold) {
166 UMA_HISTOGRAM_BOOLEAN(
167 "PerformanceMonitor.HighCPU.RendererExtensionEventProcess", true);
169 break;
172 if (cpu_usage_ > kHighCPUUtilizationThreshold &&
173 trace_trigger_handle_ != -1) {
174 content::BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
175 trace_trigger_handle_,
176 content::BackgroundTracingManager::StartedFinalizingCallback());
180 } // namespace performance_monitor