OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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/scheduler/child/idle_helper.h" | 5 #include "components/scheduler/child/idle_helper.h" |
6 | 6 |
7 #include "base/time/time.h" | 7 #include "base/time/time.h" |
8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
9 #include "base/trace_event/trace_event_argument.h" | 9 #include "base/trace_event/trace_event_argument.h" |
10 #include "components/scheduler/child/scheduler_helper.h" | 10 #include "components/scheduler/child/scheduler_helper.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 if (state_.idle_period_state() == | 272 if (state_.idle_period_state() == |
273 IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | 273 IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { |
274 // Restart long idle period ticks. | 274 // Restart long idle period ticks. |
275 helper_->ControlTaskRunner()->PostTask( | 275 helper_->ControlTaskRunner()->PostTask( |
276 FROM_HERE, enable_next_long_idle_period_closure_.callback()); | 276 FROM_HERE, enable_next_long_idle_period_closure_.callback()); |
277 } | 277 } |
278 } | 278 } |
279 | 279 |
280 base::TimeTicks IdleHelper::WillProcessIdleTask() { | 280 base::TimeTicks IdleHelper::WillProcessIdleTask() { |
281 helper_->CheckOnValidThread(); | 281 helper_->CheckOnValidThread(); |
282 DCHECK(IsInIdlePeriod(state_.idle_period_state())); | |
283 | |
284 state_.TraceIdleIdleTaskStart(); | 282 state_.TraceIdleIdleTaskStart(); |
285 return CurrentIdleTaskDeadline(); | 283 return CurrentIdleTaskDeadline(); |
286 } | 284 } |
287 | 285 |
288 void IdleHelper::DidProcessIdleTask() { | 286 void IdleHelper::DidProcessIdleTask() { |
289 helper_->CheckOnValidThread(); | 287 helper_->CheckOnValidThread(); |
290 state_.TraceIdleIdleTaskEnd(); | 288 state_.TraceIdleIdleTaskEnd(); |
291 if (IsInLongIdlePeriod(state_.idle_period_state())) { | 289 if (IsInLongIdlePeriod(state_.idle_period_state())) { |
292 UpdateLongIdlePeriodStateAfterIdleTask(); | 290 UpdateLongIdlePeriodStateAfterIdleTask(); |
293 } | 291 } |
(...skipping 24 matching lines...) Expand all Loading... |
318 } | 316 } |
319 | 317 |
320 IdleHelper::State::State(SchedulerHelper* helper, | 318 IdleHelper::State::State(SchedulerHelper* helper, |
321 Delegate* delegate, | 319 Delegate* delegate, |
322 const char* tracing_category, | 320 const char* tracing_category, |
323 const char* disabled_by_default_tracing_category, | 321 const char* disabled_by_default_tracing_category, |
324 const char* idle_period_tracing_name) | 322 const char* idle_period_tracing_name) |
325 : helper_(helper), | 323 : helper_(helper), |
326 delegate_(delegate), | 324 delegate_(delegate), |
327 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), | 325 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), |
328 nestable_events_started_(false), | 326 idle_period_trace_event_started_(false), |
| 327 running_idle_task_for_tracing_(false), |
329 tracing_category_(tracing_category), | 328 tracing_category_(tracing_category), |
330 disabled_by_default_tracing_category_( | 329 disabled_by_default_tracing_category_( |
331 disabled_by_default_tracing_category), | 330 disabled_by_default_tracing_category), |
332 idle_period_tracing_name_(idle_period_tracing_name) { | 331 idle_period_tracing_name_(idle_period_tracing_name) { |
333 } | 332 } |
334 | 333 |
335 IdleHelper::State::~State() { | 334 IdleHelper::State::~State() { |
336 } | 335 } |
337 | 336 |
338 IdleHelper::IdlePeriodState IdleHelper::State::idle_period_state() const { | 337 IdleHelper::IdlePeriodState IdleHelper::State::idle_period_state() const { |
(...skipping 14 matching lines...) Expand all Loading... |
353 helper_->CheckOnValidThread(); | 352 helper_->CheckOnValidThread(); |
354 if (new_state == idle_period_state_) { | 353 if (new_state == idle_period_state_) { |
355 DCHECK_EQ(new_deadline, idle_period_deadline_); | 354 DCHECK_EQ(new_deadline, idle_period_deadline_); |
356 return; | 355 return; |
357 } | 356 } |
358 | 357 |
359 bool is_tracing; | 358 bool is_tracing; |
360 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 359 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
361 if (is_tracing) { | 360 if (is_tracing) { |
362 base::TimeTicks now(optional_now.is_null() ? helper_->Now() : optional_now); | 361 base::TimeTicks now(optional_now.is_null() ? helper_->Now() : optional_now); |
363 TraceEventIdlePeriodStateChange(new_state, new_deadline, now); | 362 base::TraceTicks trace_now = base::TraceTicks::Now(); |
364 idle_period_deadline_for_tracing_ = | 363 idle_period_deadline_for_tracing_ = trace_now + (new_deadline - now); |
365 base::TraceTicks::Now() + (new_deadline - now); | 364 TraceEventIdlePeriodStateChange( |
| 365 new_state, running_idle_task_for_tracing_, |
| 366 idle_period_deadline_for_tracing_, trace_now); |
366 } | 367 } |
367 | 368 |
368 idle_period_state_ = new_state; | 369 idle_period_state_ = new_state; |
369 idle_period_deadline_ = new_deadline; | 370 idle_period_deadline_ = new_deadline; |
370 | 371 |
371 // Inform the delegate if we are starting or ending an idle period. | 372 // Inform the delegate if we are starting or ending an idle period. |
372 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(old_idle_period_state)) { | 373 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(old_idle_period_state)) { |
373 delegate_->OnIdlePeriodStarted(); | 374 delegate_->OnIdlePeriodStarted(); |
374 } else if (!IsInIdlePeriod(new_state) && | 375 } else if (!IsInIdlePeriod(new_state) && |
375 IsInIdlePeriod(old_idle_period_state)) { | 376 IsInIdlePeriod(old_idle_period_state)) { |
376 delegate_->OnIdlePeriodEnded(); | 377 delegate_->OnIdlePeriodEnded(); |
377 } | 378 } |
378 } | 379 } |
379 | 380 |
380 void IdleHelper::State::TraceIdleIdleTaskStart() { | 381 void IdleHelper::State::TraceIdleIdleTaskStart() { |
381 helper_->CheckOnValidThread(); | 382 helper_->CheckOnValidThread(); |
382 | 383 |
383 bool is_tracing; | 384 bool is_tracing; |
384 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 385 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
385 if (is_tracing && nestable_events_started_) { | 386 if (is_tracing) { |
386 last_idle_task_trace_time_ = base::TraceTicks::Now(); | 387 TraceEventIdlePeriodStateChange( |
387 TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( | 388 idle_period_state_, true, idle_period_deadline_for_tracing_, |
388 tracing_category_, "RunningIdleTask", this, | 389 base::TraceTicks::Now()); |
389 last_idle_task_trace_time_.ToInternalValue()); | |
390 } | 390 } |
391 } | 391 } |
392 | 392 |
393 void IdleHelper::State::TraceIdleIdleTaskEnd() { | 393 void IdleHelper::State::TraceIdleIdleTaskEnd() { |
394 helper_->CheckOnValidThread(); | 394 helper_->CheckOnValidThread(); |
395 | 395 |
396 bool is_tracing; | 396 bool is_tracing; |
397 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 397 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
398 if (is_tracing && nestable_events_started_) { | 398 if (is_tracing) { |
399 if (!idle_period_deadline_for_tracing_.is_null() && | 399 TraceEventIdlePeriodStateChange( |
400 base::TraceTicks::Now() > idle_period_deadline_for_tracing_) { | 400 idle_period_state_, false, idle_period_deadline_for_tracing_, |
401 TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( | 401 base::TraceTicks::Now()); |
402 tracing_category_, "DeadlineOverrun", this, | |
403 std::max(idle_period_deadline_for_tracing_, | |
404 last_idle_task_trace_time_).ToInternalValue()); | |
405 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "DeadlineOverrun", | |
406 this); | |
407 } | |
408 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "RunningIdleTask", this); | |
409 } | 402 } |
410 } | 403 } |
411 | 404 |
412 void IdleHelper::State::TraceEventIdlePeriodStateChange( | 405 void IdleHelper::State::TraceEventIdlePeriodStateChange( |
413 IdlePeriodState new_state, | 406 IdlePeriodState new_state, |
414 base::TimeTicks new_deadline, | 407 bool new_running_idle_task, |
415 base::TimeTicks now) { | 408 base::TraceTicks new_deadline, |
| 409 base::TraceTicks now) { |
416 TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState", | 410 TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState", |
417 "old_state", | 411 "old_state", |
418 IdleHelper::IdlePeriodStateToString(idle_period_state_), | 412 IdleHelper::IdlePeriodStateToString(idle_period_state_), |
419 "new_state", IdleHelper::IdlePeriodStateToString(new_state)); | 413 "new_state", IdleHelper::IdlePeriodStateToString(new_state)); |
420 if (nestable_events_started_) { | 414 |
421 // End async tracing events for the state we are leaving. | 415 if (idle_period_trace_event_started_ && running_idle_task_for_tracing_ && |
422 if (idle_period_state_ == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | 416 !new_running_idle_task) { |
423 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "LongIdlePeriodPaused", | 417 running_idle_task_for_tracing_ = false; |
424 this); | 418 if (!idle_period_deadline_for_tracing_.is_null() && |
425 } | 419 now > idle_period_deadline_for_tracing_) { |
426 if (IsInLongIdlePeriod(idle_period_state_) && | 420 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( |
427 !IsInLongIdlePeriod(new_state)) { | 421 tracing_category_, idle_period_tracing_name_, this, |
428 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "LongIdlePeriod", | 422 "DeadlineOverrun", |
429 this); | 423 std::max(idle_period_deadline_for_tracing_, |
430 } | 424 last_idle_task_trace_time_).ToInternalValue()); |
431 if (idle_period_state_ == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { | |
432 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "ShortIdlePeriod", | |
433 this); | |
434 } | |
435 if (IsInIdlePeriod(idle_period_state_) && !IsInIdlePeriod(new_state)) { | |
436 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
437 idle_period_tracing_name_, this); | |
438 nestable_events_started_ = false; | |
439 } | 425 } |
440 } | 426 } |
441 | 427 |
442 // Start async tracing events for the state we are entering. | 428 if (IsInIdlePeriod(new_state)) { |
443 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(idle_period_state_)) { | 429 if (!idle_period_trace_event_started_) { |
444 nestable_events_started_ = true; | 430 idle_period_trace_event_started_ = true; |
445 TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( | 431 TRACE_EVENT_ASYNC_BEGIN1( |
446 tracing_category_, idle_period_tracing_name_, this, | 432 tracing_category_, idle_period_tracing_name_, this, |
447 "idle_period_length_ms", (new_deadline - now).ToInternalValue()); | 433 "idle_period_length_ms", (new_deadline - now).ToInternalValue()); |
448 } | 434 } |
449 if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { | 435 |
450 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "ShortIdlePeriod", | 436 if (new_running_idle_task) { |
451 this); | 437 last_idle_task_trace_time_ = now; |
452 } | 438 running_idle_task_for_tracing_ = true; |
453 if (IsInLongIdlePeriod(new_state) && | 439 TRACE_EVENT_ASYNC_STEP_INTO0( |
454 !IsInLongIdlePeriod(idle_period_state_)) { | 440 tracing_category_, idle_period_tracing_name_, this, |
455 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "LongIdlePeriod", | 441 "RunningIdleTask"); |
456 this); | 442 } else if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { |
457 } | 443 TRACE_EVENT_ASYNC_STEP_INTO0( |
458 if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | 444 tracing_category_, idle_period_tracing_name_, this, |
459 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "LongIdlePeriodPaused", | 445 "ShortIdlePeriod"); |
460 this); | 446 } else if (IsInLongIdlePeriod(new_state) && |
| 447 new_state != IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { |
| 448 TRACE_EVENT_ASYNC_STEP_INTO0( |
| 449 tracing_category_, idle_period_tracing_name_, this, |
| 450 "LongIdlePeriod"); |
| 451 } else if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { |
| 452 TRACE_EVENT_ASYNC_STEP_INTO0( |
| 453 tracing_category_, idle_period_tracing_name_, this, |
| 454 "LongIdlePeriodPaused"); |
| 455 } |
| 456 } else if (idle_period_trace_event_started_) { |
| 457 idle_period_trace_event_started_ = false; |
| 458 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this); |
461 } | 459 } |
462 } | 460 } |
463 | 461 |
464 // static | 462 // static |
465 const char* IdleHelper::IdlePeriodStateToString( | 463 const char* IdleHelper::IdlePeriodStateToString( |
466 IdlePeriodState idle_period_state) { | 464 IdlePeriodState idle_period_state) { |
467 switch (idle_period_state) { | 465 switch (idle_period_state) { |
468 case IdlePeriodState::NOT_IN_IDLE_PERIOD: | 466 case IdlePeriodState::NOT_IN_IDLE_PERIOD: |
469 return "not_in_idle_period"; | 467 return "not_in_idle_period"; |
470 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: | 468 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: |
471 return "in_short_idle_period"; | 469 return "in_short_idle_period"; |
472 case IdlePeriodState::IN_LONG_IDLE_PERIOD: | 470 case IdlePeriodState::IN_LONG_IDLE_PERIOD: |
473 return "in_long_idle_period"; | 471 return "in_long_idle_period"; |
474 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: | 472 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: |
475 return "in_long_idle_period_with_max_deadline"; | 473 return "in_long_idle_period_with_max_deadline"; |
476 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: | 474 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: |
477 return "in_long_idle_period_paused"; | 475 return "in_long_idle_period_paused"; |
478 default: | 476 default: |
479 NOTREACHED(); | 477 NOTREACHED(); |
480 return nullptr; | 478 return nullptr; |
481 } | 479 } |
482 } | 480 } |
483 | 481 |
484 } // namespace scheduler | 482 } // namespace scheduler |
OLD | NEW |