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

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

Issue 1021053003: Delivering the FIRST_NONEMPTY_PAINT phase changing event to base/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@phase_splitting
Patch Set: Fixing a typo. 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"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 }; 173 };
174 174
175 // static 175 // static
176 base::LazyInstance 176 base::LazyInstance
177 <TrackingSynchronizer::RequestContext::RequestContextMap>::Leaky 177 <TrackingSynchronizer::RequestContext::RequestContextMap>::Leaky
178 TrackingSynchronizer::RequestContext::outstanding_requests_ = 178 TrackingSynchronizer::RequestContext::outstanding_requests_ =
179 LAZY_INSTANCE_INITIALIZER; 179 LAZY_INSTANCE_INITIALIZER;
180 180
181 // TrackingSynchronizer methods and members. 181 // TrackingSynchronizer methods and members.
182 182
183 TrackingSynchronizer::TrackingSynchronizer(base::TimeTicks now) 183 TrackingSynchronizer::TrackingSynchronizer(scoped_ptr<base::TickClock> clock)
184 : last_used_sequence_number_(kNeverUsableSequenceNumber), start_time_(now) { 184 : last_used_sequence_number_(kNeverUsableSequenceNumber),
185 clock_(std::move(clock)) {
Ilya Sherman 2015/04/08 23:36:14 nit: std::move is not yet permitted in Chromium co
vadimt 2015/04/09 00:15:03 Done.
185 DCHECK(!g_tracking_synchronizer); 186 DCHECK(!g_tracking_synchronizer);
186 g_tracking_synchronizer = this; 187 g_tracking_synchronizer = this;
187 phase_start_times_.push_back(now); 188 phase_start_times_.push_back(clock_->NowTicks());
188 189
189 #if !defined(OS_IOS) 190 #if !defined(OS_IOS)
190 // TODO: This ifdef and other ifdefs for OS_IOS in this file are only 191 // 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 // 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 // refactor to remove content dependencies from shared code.
193 // See crbug/472210. 194 // See crbug/472210.
194 content::ProfilerController::GetInstance()->Register(this); 195 content::ProfilerController::GetInstance()->Register(this);
195 #endif 196 #endif
196 } 197 }
197 198
(...skipping 22 matching lines...) Expand all
220 callback_object); 221 callback_object);
221 222
222 // Post a task that would be called after waiting for wait_time. This acts 223 // Post a task that would be called after waiting for wait_time. This acts
223 // as a watchdog, to cancel the requests for non-responsive processes. 224 // as a watchdog, to cancel the requests for non-responsive processes.
224 BrowserThread::PostDelayedTask( 225 BrowserThread::PostDelayedTask(
225 BrowserThread::UI, FROM_HERE, 226 BrowserThread::UI, FROM_HERE,
226 base::Bind(&RequestContext::Unregister, sequence_number), 227 base::Bind(&RequestContext::Unregister, sequence_number),
227 base::TimeDelta::FromMinutes(1)); 228 base::TimeDelta::FromMinutes(1));
228 } 229 }
229 230
231 // static
232 void TrackingSynchronizer::OnProfilingPhaseCompleted(
233 ProfilerEventProto::ProfilerEvent profiling_event) {
234 DCHECK_CURRENTLY_ON(BrowserThread::UI);
235
236 if (!g_tracking_synchronizer) {
237 // System teardown is happening.
238 return;
239 }
240
241 g_tracking_synchronizer->NotifyAllProcessesOfProfilingPhaseCompletion(
242 profiling_event);
243 }
244
230 void TrackingSynchronizer::OnPendingProcesses(int sequence_number, 245 void TrackingSynchronizer::OnPendingProcesses(int sequence_number,
231 int pending_processes, 246 int pending_processes,
232 bool end) { 247 bool end) {
233 DCHECK_CURRENTLY_ON(BrowserThread::UI); 248 DCHECK_CURRENTLY_ON(BrowserThread::UI);
234 249
235 RequestContext* request = RequestContext::GetRequestContext(sequence_number); 250 RequestContext* request = RequestContext::GetRequestContext(sequence_number);
236 if (!request) 251 if (!request)
237 return; 252 return;
238 request->AddProcessesPending(pending_processes); 253 request->AddProcessesPending(pending_processes);
239 request->SetReceivedProcessGroupCount(end); 254 request->SetReceivedProcessGroupCount(end);
(...skipping 14 matching lines...) Expand all
254 DCHECK_CURRENTLY_ON(BrowserThread::UI); 269 DCHECK_CURRENTLY_ON(BrowserThread::UI);
255 270
256 int sequence_number = GetNextAvailableSequenceNumber(); 271 int sequence_number = GetNextAvailableSequenceNumber();
257 272
258 RequestContext* request = 273 RequestContext* request =
259 RequestContext::Register(sequence_number, callback_object); 274 RequestContext::Register(sequence_number, callback_object);
260 275
261 // Increment pending process count for sending browser's profiler data. 276 // Increment pending process count for sending browser's profiler data.
262 request->IncrementProcessesPending(); 277 request->IncrementProcessesPending();
263 278
279 int current_profiling_phase = phase_completion_events_sequence_.size();
280
264 #if !defined(OS_IOS) 281 #if !defined(OS_IOS)
265 // Get profiler data from renderer and browser child processes. 282 // Get profiler data from renderer and browser child processes.
266 content::ProfilerController::GetInstance()->GetProfilerData(sequence_number); 283 content::ProfilerController::GetInstance()->GetProfilerData(
284 sequence_number, current_profiling_phase);
267 #endif 285 #endif
268 286
269 // Send process data snapshot from browser process. 287 // Send process data snapshot from browser process.
270 tracked_objects::ProcessDataSnapshot process_data_snapshot; 288 tracked_objects::ProcessDataSnapshot process_data_snapshot;
271 tracked_objects::ThreadData::Snapshot(&process_data_snapshot); 289 tracked_objects::ThreadData::Snapshot(current_profiling_phase,
290 &process_data_snapshot);
291
272 DecrementPendingProcessesAndSendData(sequence_number, process_data_snapshot, 292 DecrementPendingProcessesAndSendData(sequence_number, process_data_snapshot,
273 content::PROCESS_TYPE_BROWSER); 293 content::PROCESS_TYPE_BROWSER);
274 294
275 return sequence_number; 295 return sequence_number;
276 } 296 }
277 297
298 void TrackingSynchronizer::RegisterPhaseCompletion(
299 ProfilerEventProto::ProfilerEvent profiling_event) {
300 phase_completion_events_sequence_.push_back(profiling_event);
301 phase_start_times_.push_back(clock_->NowTicks());
302 }
303
304 void TrackingSynchronizer::NotifyAllProcessesOfProfilingPhaseCompletion(
305 ProfilerEventProto::ProfilerEvent profiling_event) {
306 DCHECK_CURRENTLY_ON(BrowserThread::UI);
307
308 if (variations::GetVariationParamValue("UMALogUploadInterval",
309 "send_split_profiles") != "true") {
310 return;
311 }
312
313 int profiling_phase = phase_completion_events_sequence_.size();
314
315 RegisterPhaseCompletion(profiling_event);
316
317 #if !defined(OS_IOS)
318 // Notify renderer and browser child processes.
319 content::ProfilerController::GetInstance()->OnProfilingPhaseCompleted(
320 profiling_phase);
321 #endif
322
323 // Notify browser process.
324 tracked_objects::ThreadData::OnProfilingPhaseCompleted(profiling_phase);
325 }
326
278 void TrackingSynchronizer::SendData( 327 void TrackingSynchronizer::SendData(
279 const tracked_objects::ProcessDataSnapshot& profiler_data, 328 const tracked_objects::ProcessDataSnapshot& profiler_data,
280 content::ProcessType process_type, 329 content::ProcessType process_type,
281 base::TimeTicks now,
282 TrackingSynchronizerObserver* observer) const { 330 TrackingSynchronizerObserver* observer) const {
283 // We are going to loop though past profiling phases and notify the request 331 // 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 332 // about each phase that is contained in profiler_data. past_events
285 // will track the set of past profiling events as we go. 333 // will track the set of past profiling events as we go.
286 ProfilerEvents past_events; 334 ProfilerEvents past_events;
287 335
288 // Go through all completed phases, and through the current one. The current 336 // Go through all completed phases, and through the current one. The current
289 // one is not in phase_completion_events_sequence_, but note the <= 337 // one is not in phase_completion_events_sequence_, but note the <=
290 // comparison. 338 // comparison.
291 for (size_t phase = 0; phase <= phase_completion_events_sequence_.size(); 339 for (size_t phase = 0; phase <= phase_completion_events_sequence_.size();
292 ++phase) { 340 ++phase) {
293 auto it = profiler_data.phased_process_data_snapshots.find(phase); 341 auto it = profiler_data.phased_process_data_snapshots.find(phase);
294 342
295 if (it != profiler_data.phased_process_data_snapshots.end()) { 343 if (it != profiler_data.phased_process_data_snapshots.end()) {
296 // If the phase is contained in the received snapshot, notify the 344 // If the phase is contained in the received snapshot, notify the
297 // request. 345 // request.
298 const base::TimeDelta phase_start = 346 const base::TimeTicks phase_start = phase_start_times_[phase];
299 phase_start_times_[phase] - start_time_; 347 const base::TimeTicks phase_finish = phase + 1 < phase_start_times_.size()
300 const base::TimeDelta phase_finish = 348 ? phase_start_times_[phase + 1]
301 (phase + 1 < phase_start_times_.size() ? phase_start_times_[phase + 1] 349 : clock_->NowTicks();
302 : now) -
303 start_time_;
304 observer->ReceivedProfilerData(it->second, profiler_data.process_id, 350 observer->ReceivedProfilerData(it->second, profiler_data.process_id,
305 process_type, phase, phase_start, 351 process_type, phase, phase_start,
306 phase_finish, past_events); 352 phase_finish, past_events);
307 } 353 }
308 354
309 if (phase < phase_completion_events_sequence_.size()) { 355 if (phase < phase_completion_events_sequence_.size()) {
310 past_events.push_back(phase_completion_events_sequence_[phase]); 356 past_events.push_back(phase_completion_events_sequence_[phase]);
311 } 357 }
312 } 358 }
313 } 359 }
314 360
315 void TrackingSynchronizer::DecrementPendingProcessesAndSendData( 361 void TrackingSynchronizer::DecrementPendingProcessesAndSendData(
316 int sequence_number, 362 int sequence_number,
317 const tracked_objects::ProcessDataSnapshot& profiler_data, 363 const tracked_objects::ProcessDataSnapshot& profiler_data,
318 content::ProcessType process_type) { 364 content::ProcessType process_type) {
319 DCHECK_CURRENTLY_ON(BrowserThread::UI); 365 DCHECK_CURRENTLY_ON(BrowserThread::UI);
320 366
321 RequestContext* request = RequestContext::GetRequestContext(sequence_number); 367 RequestContext* request = RequestContext::GetRequestContext(sequence_number);
322 if (!request) 368 if (!request)
323 return; 369 return;
324 370
325 TrackingSynchronizerObserver* observer = request->callback_object_.get(); 371 TrackingSynchronizerObserver* observer = request->callback_object_.get();
326 if (observer) 372 if (observer)
327 SendData(profiler_data, process_type, base::TimeTicks::Now(), observer); 373 SendData(profiler_data, process_type, observer);
328 374
329 // Delete request if we have heard back from all child processes. 375 // Delete request if we have heard back from all child processes.
330 request->DecrementProcessesPending(); 376 request->DecrementProcessesPending();
331 request->DeleteIfAllDone(); 377 request->DeleteIfAllDone();
332 } 378 }
333 379
334 int TrackingSynchronizer::GetNextAvailableSequenceNumber() { 380 int TrackingSynchronizer::GetNextAvailableSequenceNumber() {
335 DCHECK_CURRENTLY_ON(BrowserThread::UI); 381 DCHECK_CURRENTLY_ON(BrowserThread::UI);
336 382
337 ++last_used_sequence_number_; 383 ++last_used_sequence_number_;
338 384
339 // Watch out for wrapping to a negative number. 385 // Watch out for wrapping to a negative number.
340 if (last_used_sequence_number_ < 0) 386 if (last_used_sequence_number_ < 0)
341 last_used_sequence_number_ = 1; 387 last_used_sequence_number_ = 1;
342 return last_used_sequence_number_; 388 return last_used_sequence_number_;
343 } 389 }
344 390
345 } // namespace metrics 391 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698