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

Side by Side Diff: components/metrics/profiler/tracking_synchronizer.cc

Issue 985773002: Introducing phased profiling framework (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@write_to_file
Patch Set: Fixing Android compile errors. Created 5 years, 8 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 "components/metrics/profiler/tracking_synchronizer.h" 5 #include "components/metrics/profiler/tracking_synchronizer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/threading/thread.h" 9 #include "base/threading/thread.h"
10 #include "base/tracked_objects.h" 10 #include "base/tracked_objects.h"
11 #include "components/metrics/profiler/tracking_synchronizer_observer.h" 11 #include "components/metrics/profiler/tracking_synchronizer_observer.h"
12 #include "components/variations/variations_associated_data.h"
12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/profiler_controller.h" 14 #include "content/public/browser/profiler_controller.h"
14 #include "content/public/common/process_type.h" 15 #include "content/public/common/process_type.h"
15 16
16 using base::TimeTicks; 17 using base::TimeTicks;
17 using content::BrowserThread; 18 using content::BrowserThread;
18 19
19 namespace metrics { 20 namespace metrics {
20 21
21 namespace { 22 namespace {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 }; 173 };
173 174
174 // static 175 // static
175 base::LazyInstance 176 base::LazyInstance
176 <TrackingSynchronizer::RequestContext::RequestContextMap>::Leaky 177 <TrackingSynchronizer::RequestContext::RequestContextMap>::Leaky
177 TrackingSynchronizer::RequestContext::outstanding_requests_ = 178 TrackingSynchronizer::RequestContext::outstanding_requests_ =
178 LAZY_INSTANCE_INITIALIZER; 179 LAZY_INSTANCE_INITIALIZER;
179 180
180 // TrackingSynchronizer methods and members. 181 // TrackingSynchronizer methods and members.
181 182
182 TrackingSynchronizer::TrackingSynchronizer() 183 TrackingSynchronizer::TrackingSynchronizer(base::TimeTicks now)
183 : last_used_sequence_number_(kNeverUsableSequenceNumber) { 184 : last_used_sequence_number_(kNeverUsableSequenceNumber), start_time_(now) {
184 DCHECK(!g_tracking_synchronizer); 185 DCHECK(!g_tracking_synchronizer);
185 g_tracking_synchronizer = this; 186 g_tracking_synchronizer = this;
187 phase_start_times_.push_back(now);
188
189 #if !defined(OS_IOS)
190 // TODO: This ifdef and other ifdefs for OS_IOS in this file are only
191 // short-term hacks to make this compile on iOS, and the proper solution is to
192 // refactor to remove content dependencies from shared code.
193 // See crbug/472210.
186 content::ProfilerController::GetInstance()->Register(this); 194 content::ProfilerController::GetInstance()->Register(this);
195 #endif
187 } 196 }
188 197
189 TrackingSynchronizer::~TrackingSynchronizer() { 198 TrackingSynchronizer::~TrackingSynchronizer() {
199 #if !defined(OS_IOS)
190 content::ProfilerController::GetInstance()->Unregister(this); 200 content::ProfilerController::GetInstance()->Unregister(this);
201 #endif
191 202
192 // Just in case we have any pending tasks, clear them out. 203 // Just in case we have any pending tasks, clear them out.
193 RequestContext::OnShutdown(); 204 RequestContext::OnShutdown();
194 205
195 g_tracking_synchronizer = NULL; 206 g_tracking_synchronizer = NULL;
196 } 207 }
197 208
198 // static 209 // static
199 void TrackingSynchronizer::FetchProfilerDataAsynchronously( 210 void TrackingSynchronizer::FetchProfilerDataAsynchronously(
200 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { 211 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) {
(...skipping 24 matching lines...) Expand all
225 if (!request) 236 if (!request)
226 return; 237 return;
227 request->AddProcessesPending(pending_processes); 238 request->AddProcessesPending(pending_processes);
228 request->SetReceivedProcessGroupCount(end); 239 request->SetReceivedProcessGroupCount(end);
229 request->DeleteIfAllDone(); 240 request->DeleteIfAllDone();
230 } 241 }
231 242
232 void TrackingSynchronizer::OnProfilerDataCollected( 243 void TrackingSynchronizer::OnProfilerDataCollected(
233 int sequence_number, 244 int sequence_number,
234 const tracked_objects::ProcessDataSnapshot& profiler_data, 245 const tracked_objects::ProcessDataSnapshot& profiler_data,
235 int process_type) { 246 content::ProcessType process_type) {
236 DCHECK_CURRENTLY_ON(BrowserThread::UI); 247 DCHECK_CURRENTLY_ON(BrowserThread::UI);
237 DecrementPendingProcessesAndSendData(sequence_number, profiler_data, 248 DecrementPendingProcessesAndSendData(sequence_number, profiler_data,
238 process_type); 249 process_type);
239 } 250 }
240 251
241 int TrackingSynchronizer::RegisterAndNotifyAllProcesses( 252 int TrackingSynchronizer::RegisterAndNotifyAllProcesses(
242 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { 253 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) {
243 DCHECK_CURRENTLY_ON(BrowserThread::UI); 254 DCHECK_CURRENTLY_ON(BrowserThread::UI);
244 255
245 int sequence_number = GetNextAvailableSequenceNumber(); 256 int sequence_number = GetNextAvailableSequenceNumber();
246 257
247 RequestContext* request = 258 RequestContext* request =
248 RequestContext::Register(sequence_number, callback_object); 259 RequestContext::Register(sequence_number, callback_object);
249 260
250 // Increment pending process count for sending browser's profiler data. 261 // Increment pending process count for sending browser's profiler data.
251 request->IncrementProcessesPending(); 262 request->IncrementProcessesPending();
252 263
264 #if !defined(OS_IOS)
253 // Get profiler data from renderer and browser child processes. 265 // Get profiler data from renderer and browser child processes.
254 content::ProfilerController::GetInstance()->GetProfilerData(sequence_number); 266 content::ProfilerController::GetInstance()->GetProfilerData(sequence_number);
267 #endif
255 268
256 // Send profiler_data from browser process. 269 // Send process data snapshot from browser process.
257 tracked_objects::ProcessDataSnapshot process_data; 270 tracked_objects::ProcessDataSnapshot process_data_snapshot;
258 tracked_objects::ThreadData::Snapshot(&process_data); 271 tracked_objects::ThreadData::Snapshot(&process_data_snapshot);
259 DecrementPendingProcessesAndSendData(sequence_number, process_data, 272 DecrementPendingProcessesAndSendData(sequence_number, process_data_snapshot,
260 content::PROCESS_TYPE_BROWSER); 273 content::PROCESS_TYPE_BROWSER);
261 274
262 return sequence_number; 275 return sequence_number;
263 } 276 }
264 277
278 void TrackingSynchronizer::SendData(
279 const tracked_objects::ProcessDataSnapshot& profiler_data,
280 content::ProcessType process_type,
281 base::TimeTicks now,
282 TrackingSynchronizerObserver* observer) const {
283 // We are going to loop though past profiling phases and notify the request
284 // about each phase that is contained in profiler_data. past_events
285 // will track the set of past profiling events as we go.
286 ProfilerEvents past_events;
287
288 // Go through all completed phases, and through the current one. The current
289 // one is not in phase_completion_events_sequence_, but note the <=
290 // comparison.
291 for (size_t phase = 0; phase <= phase_completion_events_sequence_.size();
292 ++phase) {
293 auto it = profiler_data.phased_process_data_snapshots.find(phase);
294
295 if (it != profiler_data.phased_process_data_snapshots.end()) {
296 // If the phase is contained in the received snapshot, notify the
297 // request.
298 const base::TimeDelta phase_start =
299 phase_start_times_[phase] - start_time_;
300 const base::TimeDelta phase_finish =
301 (phase + 1 < phase_start_times_.size() ? phase_start_times_[phase + 1]
302 : now) -
303 start_time_;
304 observer->ReceivedProfilerData(it->second, profiler_data.process_id,
305 process_type, phase, phase_start,
306 phase_finish, past_events);
307 }
308
309 if (phase < phase_completion_events_sequence_.size()) {
310 past_events.push_back(phase_completion_events_sequence_[phase]);
311 }
312 }
313 }
314
265 void TrackingSynchronizer::DecrementPendingProcessesAndSendData( 315 void TrackingSynchronizer::DecrementPendingProcessesAndSendData(
266 int sequence_number, 316 int sequence_number,
267 const tracked_objects::ProcessDataSnapshot& profiler_data, 317 const tracked_objects::ProcessDataSnapshot& profiler_data,
268 int process_type) { 318 content::ProcessType process_type) {
269 DCHECK_CURRENTLY_ON(BrowserThread::UI); 319 DCHECK_CURRENTLY_ON(BrowserThread::UI);
270 320
271 RequestContext* request = RequestContext::GetRequestContext(sequence_number); 321 RequestContext* request = RequestContext::GetRequestContext(sequence_number);
272 if (!request) 322 if (!request)
273 return; 323 return;
274 324
275 if (request->callback_object_.get()) { 325 TrackingSynchronizerObserver* observer = request->callback_object_.get();
276 request->callback_object_ 326 if (observer)
277 ->ReceivedProfilerData(profiler_data, process_type); 327 SendData(profiler_data, process_type, base::TimeTicks::Now(), observer);
278 }
279 328
280 // Delete request if we have heard back from all child processes. 329 // Delete request if we have heard back from all child processes.
281 request->DecrementProcessesPending(); 330 request->DecrementProcessesPending();
282 request->DeleteIfAllDone(); 331 request->DeleteIfAllDone();
283 } 332 }
284 333
285 int TrackingSynchronizer::GetNextAvailableSequenceNumber() { 334 int TrackingSynchronizer::GetNextAvailableSequenceNumber() {
286 DCHECK_CURRENTLY_ON(BrowserThread::UI); 335 DCHECK_CURRENTLY_ON(BrowserThread::UI);
287 336
288 ++last_used_sequence_number_; 337 ++last_used_sequence_number_;
289 338
290 // Watch out for wrapping to a negative number. 339 // Watch out for wrapping to a negative number.
291 if (last_used_sequence_number_ < 0) 340 if (last_used_sequence_number_ < 0)
292 last_used_sequence_number_ = 1; 341 last_used_sequence_number_ = 1;
293 return last_used_sequence_number_; 342 return last_used_sequence_number_;
294 } 343 }
295 344
296 } // namespace metrics 345 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/profiler/tracking_synchronizer.h ('k') | components/metrics/profiler/tracking_synchronizer_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698