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

Side by Side Diff: chrome/browser/performance_monitor/performance_monitor.cc

Issue 2181493002: Return unique_ptrs from base::ProcessMetrics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove os_resource_win.* Created 4 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/performance_monitor/performance_monitor.h" 5 #include "chrome/browser/performance_monitor/performance_monitor.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/memory/singleton.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/process/process_iterator.h" 11 #include "base/process/process_iterator.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "content/public/browser/browser_child_process_host.h" 14 #include "content/public/browser/browser_child_process_host.h"
15 #include "content/public/browser/browser_child_process_host_iterator.h" 15 #include "content/public/browser/browser_child_process_host_iterator.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/child_process_data.h" 17 #include "content/public/browser/child_process_data.h"
18 #include "content/public/browser/render_process_host.h" 18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/common/content_constants.h" 19 #include "content/public/common/content_constants.h"
20 20
21 #if defined(ENABLE_EXTENSIONS) 21 #if defined(ENABLE_EXTENSIONS)
22 #include "extensions/browser/extension_host.h" 22 #include "extensions/browser/extension_host.h"
23 #include "extensions/browser/extension_registry.h" 23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/common/manifest_handlers/background_info.h" 24 #include "extensions/common/manifest_handlers/background_info.h"
25 #endif 25 #endif
26 26
27 using content::BrowserThread; 27 using content::BrowserThread;
28 28
29 namespace performance_monitor {
30
29 namespace { 31 namespace {
30 32
31 // The default interval at which PerformanceMonitor performs its timed 33 // The default interval at which PerformanceMonitor performs its timed
32 // collections. 34 // collections.
33 const int kGatherIntervalInSeconds = 120; 35 const int kGatherIntervalInSeconds = 120;
34 36
35 } // namespace 37 base::LazyInstance<PerformanceMonitor> g_monitor = LAZY_INSTANCE_INITIALIZER;
36
37 namespace performance_monitor {
38
39 PerformanceMonitor::PerformanceMonitor() {
40 }
41
42 PerformanceMonitor::~PerformanceMonitor() {
43 }
44
45 // static
46 PerformanceMonitor* PerformanceMonitor::GetInstance() {
47 return base::Singleton<PerformanceMonitor>::get();
48 }
49
50 void PerformanceMonitor::StartGatherCycle() {
51 DCHECK_CURRENTLY_ON(BrowserThread::UI);
52 repeating_timer_.Start(FROM_HERE,
53 base::TimeDelta::FromSeconds(kGatherIntervalInSeconds),
54 this, &PerformanceMonitor::GatherMetricsMapOnUIThread);
55 }
56
57 namespace {
58 38
59 void GatherMetricsForRenderProcess(content::RenderProcessHost* host, 39 void GatherMetricsForRenderProcess(content::RenderProcessHost* host,
60 ProcessMetricsMetadata& data) { 40 ProcessMetricsMetadata* data) {
61 DCHECK_CURRENTLY_ON(BrowserThread::UI); 41 DCHECK_CURRENTLY_ON(BrowserThread::UI);
62 #if defined(ENABLE_EXTENSIONS) 42 #if defined(ENABLE_EXTENSIONS)
63 content::BrowserContext* browser_context = host->GetBrowserContext(); 43 content::BrowserContext* browser_context = host->GetBrowserContext();
64 extensions::ProcessMap* extension_process_map = 44 extensions::ProcessMap* extension_process_map =
65 extensions::ProcessMap::Get(browser_context); 45 extensions::ProcessMap::Get(browser_context);
66 46
67 std::set<std::string> extension_ids = 47 std::set<std::string> extension_ids =
68 extension_process_map->GetExtensionsInProcess(host->GetID()); 48 extension_process_map->GetExtensionsInProcess(host->GetID());
69 49
70 // We only collect more granular metrics when there's only one extension 50 // We only collect more granular metrics when there's only one extension
71 // running in a given renderer, to reduce noise. 51 // running in a given renderer, to reduce noise.
72 if (extension_ids.size() != 1) 52 if (extension_ids.size() != 1)
73 return; 53 return;
74 54
75 extensions::ExtensionRegistry* extension_registry = 55 extensions::ExtensionRegistry* extension_registry =
76 extensions::ExtensionRegistry::Get(browser_context); 56 extensions::ExtensionRegistry::Get(browser_context);
77 57
78 const extensions::Extension* extension = 58 const extensions::Extension* extension =
79 extension_registry->enabled_extensions().GetByID(*extension_ids.begin()); 59 extension_registry->enabled_extensions().GetByID(*extension_ids.begin());
80 60
81 if (!extension) 61 if (!extension)
82 return; 62 return;
83 63
84 if (extensions::BackgroundInfo::HasPersistentBackgroundPage(extension)) { 64 data->process_subtype =
85 data.process_subtype = kProcessSubtypeExtensionPersistent; 65 extensions::BackgroundInfo::HasPersistentBackgroundPage(extension)
86 } else { 66 ? kProcessSubtypeExtensionPersistent
87 data.process_subtype = kProcessSubtypeExtensionEvent; 67 : kProcessSubtypeExtensionEvent;
88 }
89 #endif 68 #endif
90 } 69 }
91 70
92 } // namespace 71 } // namespace
93 72
73 PerformanceMonitor::PerformanceMonitor() {}
74
75 PerformanceMonitor::~PerformanceMonitor() {}
76
77 // static
78 PerformanceMonitor* PerformanceMonitor::GetInstance() {
79 return g_monitor.Pointer();
80 }
81
82 void PerformanceMonitor::StartGatherCycle() {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
84 repeating_timer_.Start(FROM_HERE,
85 base::TimeDelta::FromSeconds(kGatherIntervalInSeconds),
86 this, &PerformanceMonitor::GatherMetricsMapOnUIThread);
87 }
88
94 void PerformanceMonitor::GatherMetricsMapOnUIThread() { 89 void PerformanceMonitor::GatherMetricsMapOnUIThread() {
95 DCHECK_CURRENTLY_ON(BrowserThread::UI); 90 DCHECK_CURRENTLY_ON(BrowserThread::UI);
96 91
97 static int current_update_sequence = 0; 92 static int current_update_sequence = 0;
98 // Even in the "somewhat" unlikely event this wraps around, 93 // Even in the "somewhat" unlikely event this wraps around,
99 // it doesn't matter. We just check it for inequality. 94 // it doesn't matter. We just check it for inequality.
100 current_update_sequence++; 95 current_update_sequence++;
101 96
102 // Find all render child processes; has to be done on the UI thread. 97 // Find all render child processes; has to be done on the UI thread.
103 for (content::RenderProcessHost::iterator rph_iter = 98 for (content::RenderProcessHost::iterator rph_iter =
104 content::RenderProcessHost::AllHostsIterator(); 99 content::RenderProcessHost::AllHostsIterator();
105 !rph_iter.IsAtEnd(); rph_iter.Advance()) { 100 !rph_iter.IsAtEnd(); rph_iter.Advance()) {
106 content::RenderProcessHost* host = rph_iter.GetCurrentValue(); 101 content::RenderProcessHost* host = rph_iter.GetCurrentValue();
107 ProcessMetricsMetadata data; 102 ProcessMetricsMetadata data;
108 data.process_type = content::PROCESS_TYPE_RENDERER; 103 data.process_type = content::PROCESS_TYPE_RENDERER;
109 data.handle = host->GetHandle(); 104 data.handle = host->GetHandle();
110 105
111 GatherMetricsForRenderProcess(host, data); 106 GatherMetricsForRenderProcess(host, &data);
112 MarkProcessAsAlive(data, current_update_sequence); 107 MarkProcessAsAlive(data, current_update_sequence);
113 } 108 }
114 109
115 BrowserThread::PostTask( 110 BrowserThread::PostTask(
116 BrowserThread::IO, FROM_HERE, 111 BrowserThread::IO, FROM_HERE,
117 base::Bind(&PerformanceMonitor::GatherMetricsMapOnIOThread, 112 base::Bind(&PerformanceMonitor::GatherMetricsMapOnIOThread,
118 base::Unretained(this), current_update_sequence)); 113 base::Unretained(this), current_update_sequence));
119 } 114 }
120 115
121 void PerformanceMonitor::MarkProcessAsAlive( 116 void PerformanceMonitor::MarkProcessAsAlive(
122 const ProcessMetricsMetadata& process_data, 117 const ProcessMetricsMetadata& process_data,
123 int current_update_sequence) { 118 int current_update_sequence) {
124 DCHECK_CURRENTLY_ON(BrowserThread::UI); 119 DCHECK_CURRENTLY_ON(BrowserThread::UI);
125 120
126 const base::ProcessHandle& handle = process_data.handle; 121 const base::ProcessHandle& handle = process_data.handle;
127 if (handle == base::kNullProcessHandle) { 122 if (handle == base::kNullProcessHandle) {
128 // Process may not be valid yet. 123 // Process may not be valid yet.
129 return; 124 return;
130 } 125 }
131 126
132 MetricsMap::iterator process_metrics_iter = metrics_map_.find(handle); 127 MetricsMap::iterator process_metrics_iter = metrics_map_.find(handle);
133 if (process_metrics_iter == metrics_map_.end()) { 128 if (process_metrics_iter == metrics_map_.end()) {
134 // If we're not already watching the process, let's initialize it. 129 // If we're not already watching the process, let's initialize it.
135 metrics_map_[handle].Initialize(process_data, current_update_sequence); 130 metrics_map_[handle] = base::MakeUnique<ProcessMetricsHistory>();
131 metrics_map_[handle]->Initialize(process_data, current_update_sequence);
136 } else { 132 } else {
137 // If we are watching the process, touch it to keep it alive. 133 // If we are watching the process, touch it to keep it alive.
138 ProcessMetricsHistory& process_metrics = process_metrics_iter->second; 134 ProcessMetricsHistory* process_metrics = process_metrics_iter->second.get();
139 process_metrics.set_last_update_sequence(current_update_sequence); 135 process_metrics->set_last_update_sequence(current_update_sequence);
140 } 136 }
141 } 137 }
142 138
143 void PerformanceMonitor::GatherMetricsMapOnIOThread( 139 void PerformanceMonitor::GatherMetricsMapOnIOThread(
144 int current_update_sequence) { 140 int current_update_sequence) {
145 DCHECK_CURRENTLY_ON(BrowserThread::IO); 141 DCHECK_CURRENTLY_ON(BrowserThread::IO);
146 142
147 std::unique_ptr<std::vector<ProcessMetricsMetadata>> process_data_list( 143 auto process_data_list =
148 new std::vector<ProcessMetricsMetadata>()); 144 base::MakeUnique<std::vector<ProcessMetricsMetadata>>();
149 145
150 // Find all child processes (does not include renderers), which has to be 146 // Find all child processes (does not include renderers), which has to be
151 // done on the IO thread. 147 // done on the IO thread.
152 for (content::BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { 148 for (content::BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
153 ProcessMetricsMetadata child_process_data; 149 ProcessMetricsMetadata child_process_data;
154 child_process_data.handle = iter.GetData().handle; 150 child_process_data.handle = iter.GetData().handle;
155 child_process_data.process_type = iter.GetData().process_type; 151 child_process_data.process_type = iter.GetData().process_type;
156 152
157 if (iter.GetData().name == base::ASCIIToUTF16(content::kFlashPluginName)) { 153 if (iter.GetData().name == base::ASCIIToUTF16(content::kFlashPluginName)) {
158 child_process_data.process_subtype = kProcessSubtypePPAPIFlash; 154 child_process_data.process_subtype = kProcessSubtypePPAPIFlash;
(...skipping 13 matching lines...) Expand all
172 base::Bind(&PerformanceMonitor::MarkProcessesAsAliveOnUIThread, 168 base::Bind(&PerformanceMonitor::MarkProcessesAsAliveOnUIThread,
173 base::Unretained(this), 169 base::Unretained(this),
174 base::Passed(std::move(process_data_list)), 170 base::Passed(std::move(process_data_list)),
175 current_update_sequence)); 171 current_update_sequence));
176 } 172 }
177 173
178 void PerformanceMonitor::MarkProcessesAsAliveOnUIThread( 174 void PerformanceMonitor::MarkProcessesAsAliveOnUIThread(
179 std::unique_ptr<std::vector<ProcessMetricsMetadata>> process_data_list, 175 std::unique_ptr<std::vector<ProcessMetricsMetadata>> process_data_list,
180 int current_update_sequence) { 176 int current_update_sequence) {
181 DCHECK_CURRENTLY_ON(BrowserThread::UI); 177 DCHECK_CURRENTLY_ON(BrowserThread::UI);
182 for (size_t i = 0; i < process_data_list->size(); ++i) { 178 for (const ProcessMetricsMetadata& data : *process_data_list)
183 MarkProcessAsAlive((*process_data_list)[i], current_update_sequence); 179 MarkProcessAsAlive(data, current_update_sequence);
184 }
185 180
186 BrowserThread::PostTask( 181 BrowserThread::PostTask(
187 BrowserThread::IO, FROM_HERE, 182 BrowserThread::IO, FROM_HERE,
188 base::Bind(&PerformanceMonitor::UpdateMetricsOnIOThread, 183 base::Bind(&PerformanceMonitor::UpdateMetricsOnIOThread,
189 base::Unretained(this), current_update_sequence)); 184 base::Unretained(this), current_update_sequence));
190 } 185 }
191 186
192 void PerformanceMonitor::UpdateMetricsOnIOThread(int current_update_sequence) { 187 void PerformanceMonitor::UpdateMetricsOnIOThread(int current_update_sequence) {
193 DCHECK_CURRENTLY_ON(BrowserThread::IO); 188 DCHECK_CURRENTLY_ON(BrowserThread::IO);
194 // Update metrics for all watched processes; remove dead entries from the map. 189 // Update metrics for all watched processes; remove dead entries from the map.
195 MetricsMap::iterator iter = metrics_map_.begin(); 190 MetricsMap::iterator iter = metrics_map_.begin();
196 while (iter != metrics_map_.end()) { 191 while (iter != metrics_map_.end()) {
197 ProcessMetricsHistory& process_metrics = iter->second; 192 ProcessMetricsHistory* process_metrics = iter->second.get();
198 if (process_metrics.last_update_sequence() != current_update_sequence) { 193 if (process_metrics->last_update_sequence() != current_update_sequence) {
199 // Not touched this iteration; let's get rid of it. 194 // Not touched this iteration; let's get rid of it.
200 metrics_map_.erase(iter++); 195 metrics_map_.erase(iter++);
201 } else { 196 } else {
202 process_metrics.SampleMetrics(); 197 process_metrics->SampleMetrics();
203 ++iter; 198 ++iter;
204 } 199 }
205 } 200 }
206 201
207 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 202 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
208 base::Bind(&PerformanceMonitor::RunTriggersUIThread, 203 base::Bind(&PerformanceMonitor::RunTriggersUIThread,
209 base::Unretained(this))); 204 base::Unretained(this)));
210 } 205 }
211 206
212 void PerformanceMonitor::RunTriggersUIThread() { 207 void PerformanceMonitor::RunTriggersUIThread() {
213 DCHECK_CURRENTLY_ON(BrowserThread::UI); 208 DCHECK_CURRENTLY_ON(BrowserThread::UI);
214 for (auto it = metrics_map_.begin(); it != metrics_map_.end(); ++it) { 209 for (auto& metrics : metrics_map_)
215 it->second.RunPerformanceTriggers(); 210 metrics.second->RunPerformanceTriggers();
216 }
217 211
218 StartGatherCycle(); 212 StartGatherCycle();
219 } 213 }
220 214
221 } // namespace performance_monitor 215 } // namespace performance_monitor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698