| 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 "platform/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/base/real_time_domain.h" | 10 #include "platform/scheduler/base/real_time_domain.h" |
| 11 #include "components/scheduler/base/task_queue.h" | 11 #include "public/platform/scheduler/base/task_queue.h" |
| 12 #include "components/scheduler/base/task_queue_manager.h" | 12 #include "platform/scheduler/base/task_queue_manager.h" |
| 13 #include "components/scheduler/child/scheduler_helper.h" | 13 #include "platform/scheduler/child/scheduler_helper.h" |
| 14 #include "components/scheduler/child/scheduler_tqm_delegate.h" | 14 #include "platform/scheduler/child/scheduler_tqm_delegate.h" |
| 15 | 15 |
| 16 namespace blink { |
| 16 namespace scheduler { | 17 namespace scheduler { |
| 17 | 18 |
| 18 IdleHelper::IdleHelper( | 19 IdleHelper::IdleHelper( |
| 19 SchedulerHelper* helper, | 20 SchedulerHelper* helper, |
| 20 Delegate* delegate, | 21 Delegate* delegate, |
| 21 const char* tracing_category, | 22 const char* tracing_category, |
| 22 const char* disabled_by_default_tracing_category, | 23 const char* disabled_by_default_tracing_category, |
| 23 const char* idle_period_tracing_name, | 24 const char* idle_period_tracing_name, |
| 24 base::TimeDelta required_quiescence_duration_before_long_idle_period) | 25 base::TimeDelta required_quiescence_duration_before_long_idle_period) |
| 25 : helper_(helper), | 26 : helper_(helper), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 50 idle_queue_->SetQueueEnabled(false); | 51 idle_queue_->SetQueueEnabled(false); |
| 51 idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); | 52 idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); |
| 52 | 53 |
| 53 helper_->AddTaskObserver(this); | 54 helper_->AddTaskObserver(this); |
| 54 } | 55 } |
| 55 | 56 |
| 56 IdleHelper::~IdleHelper() { | 57 IdleHelper::~IdleHelper() { |
| 57 helper_->RemoveTaskObserver(this); | 58 helper_->RemoveTaskObserver(this); |
| 58 } | 59 } |
| 59 | 60 |
| 60 IdleHelper::Delegate::Delegate() { | 61 IdleHelper::Delegate::Delegate() {} |
| 61 } | |
| 62 | 62 |
| 63 IdleHelper::Delegate::~Delegate() { | 63 IdleHelper::Delegate::~Delegate() {} |
| 64 } | |
| 65 | 64 |
| 66 scoped_refptr<SingleThreadIdleTaskRunner> IdleHelper::IdleTaskRunner() { | 65 scoped_refptr<SingleThreadIdleTaskRunner> IdleHelper::IdleTaskRunner() { |
| 67 helper_->CheckOnValidThread(); | 66 helper_->CheckOnValidThread(); |
| 68 return idle_task_runner_; | 67 return idle_task_runner_; |
| 69 } | 68 } |
| 70 | 69 |
| 71 IdleHelper::IdlePeriodState IdleHelper::ComputeNewLongIdlePeriodState( | 70 IdleHelper::IdlePeriodState IdleHelper::ComputeNewLongIdlePeriodState( |
| 72 const base::TimeTicks now, | 71 const base::TimeTicks now, |
| 73 base::TimeDelta* next_long_idle_period_delay_out) { | 72 base::TimeDelta* next_long_idle_period_delay_out) { |
| 74 helper_->CheckOnValidThread(); | 73 helper_->CheckOnValidThread(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 | 190 |
| 192 // If we weren't already within an idle period then early-out. | 191 // If we weren't already within an idle period then early-out. |
| 193 if (!IsInIdlePeriod(state_.idle_period_state())) | 192 if (!IsInIdlePeriod(state_.idle_period_state())) |
| 194 return; | 193 return; |
| 195 | 194 |
| 196 idle_queue_->SetQueueEnabled(false); | 195 idle_queue_->SetQueueEnabled(false); |
| 197 state_.UpdateState(IdlePeriodState::NOT_IN_IDLE_PERIOD, base::TimeTicks(), | 196 state_.UpdateState(IdlePeriodState::NOT_IN_IDLE_PERIOD, base::TimeTicks(), |
| 198 base::TimeTicks()); | 197 base::TimeTicks()); |
| 199 } | 198 } |
| 200 | 199 |
| 201 void IdleHelper::WillProcessTask(const base::PendingTask& pending_task) { | 200 void IdleHelper::WillProcessTask(const base::PendingTask& pending_task) {} |
| 202 } | |
| 203 | 201 |
| 204 void IdleHelper::DidProcessTask(const base::PendingTask& pending_task) { | 202 void IdleHelper::DidProcessTask(const base::PendingTask& pending_task) { |
| 205 helper_->CheckOnValidThread(); | 203 helper_->CheckOnValidThread(); |
| 206 TRACE_EVENT0(disabled_by_default_tracing_category_, "DidProcessTask"); | 204 TRACE_EVENT0(disabled_by_default_tracing_category_, "DidProcessTask"); |
| 207 if (IsInIdlePeriod(state_.idle_period_state()) && | 205 if (IsInIdlePeriod(state_.idle_period_state()) && |
| 208 state_.idle_period_state() != | 206 state_.idle_period_state() != |
| 209 IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED && | 207 IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED && |
| 210 helper_->scheduler_tqm_delegate()->NowTicks() >= | 208 helper_->scheduler_tqm_delegate()->NowTicks() >= |
| 211 state_.idle_period_deadline()) { | 209 state_.idle_period_deadline()) { |
| 212 // If the idle period deadline has now been reached, either end the idle | 210 // If the idle period deadline has now been reached, either end the idle |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 const char* disabled_by_default_tracing_category, | 325 const char* disabled_by_default_tracing_category, |
| 328 const char* idle_period_tracing_name) | 326 const char* idle_period_tracing_name) |
| 329 : helper_(helper), | 327 : helper_(helper), |
| 330 delegate_(delegate), | 328 delegate_(delegate), |
| 331 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), | 329 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), |
| 332 idle_period_trace_event_started_(false), | 330 idle_period_trace_event_started_(false), |
| 333 running_idle_task_for_tracing_(false), | 331 running_idle_task_for_tracing_(false), |
| 334 tracing_category_(tracing_category), | 332 tracing_category_(tracing_category), |
| 335 disabled_by_default_tracing_category_( | 333 disabled_by_default_tracing_category_( |
| 336 disabled_by_default_tracing_category), | 334 disabled_by_default_tracing_category), |
| 337 idle_period_tracing_name_(idle_period_tracing_name) { | 335 idle_period_tracing_name_(idle_period_tracing_name) {} |
| 338 } | |
| 339 | 336 |
| 340 IdleHelper::State::~State() { | 337 IdleHelper::State::~State() {} |
| 341 } | |
| 342 | 338 |
| 343 IdleHelper::IdlePeriodState IdleHelper::State::idle_period_state() const { | 339 IdleHelper::IdlePeriodState IdleHelper::State::idle_period_state() const { |
| 344 helper_->CheckOnValidThread(); | 340 helper_->CheckOnValidThread(); |
| 345 return idle_period_state_; | 341 return idle_period_state_; |
| 346 } | 342 } |
| 347 | 343 |
| 348 base::TimeTicks IdleHelper::State::idle_period_deadline() const { | 344 base::TimeTicks IdleHelper::State::idle_period_deadline() const { |
| 349 helper_->CheckOnValidThread(); | 345 helper_->CheckOnValidThread(); |
| 350 return idle_period_deadline_; | 346 return idle_period_deadline_; |
| 351 } | 347 } |
| 352 | 348 |
| 353 void IdleHelper::State::UpdateState(IdlePeriodState new_state, | 349 void IdleHelper::State::UpdateState(IdlePeriodState new_state, |
| 354 base::TimeTicks new_deadline, | 350 base::TimeTicks new_deadline, |
| 355 base::TimeTicks optional_now) { | 351 base::TimeTicks optional_now) { |
| 356 IdlePeriodState old_idle_period_state = idle_period_state_; | 352 IdlePeriodState old_idle_period_state = idle_period_state_; |
| 357 | 353 |
| 358 helper_->CheckOnValidThread(); | 354 helper_->CheckOnValidThread(); |
| 359 if (new_state == idle_period_state_) { | 355 if (new_state == idle_period_state_) { |
| 360 DCHECK_EQ(new_deadline, idle_period_deadline_); | 356 DCHECK_EQ(new_deadline, idle_period_deadline_); |
| 361 return; | 357 return; |
| 362 } | 358 } |
| 363 | 359 |
| 364 bool is_tracing; | 360 bool is_tracing; |
| 365 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 361 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
| 366 if (is_tracing) { | 362 if (is_tracing) { |
| 367 base::TimeTicks now(optional_now.is_null() | 363 base::TimeTicks now(optional_now.is_null() |
| 368 ? helper_->scheduler_tqm_delegate()->NowTicks() | 364 ? helper_->scheduler_tqm_delegate()->NowTicks() |
| 369 : optional_now); | 365 : optional_now); |
| 370 TraceEventIdlePeriodStateChange( | 366 TraceEventIdlePeriodStateChange(new_state, running_idle_task_for_tracing_, |
| 371 new_state, running_idle_task_for_tracing_, idle_period_deadline_, now); | 367 idle_period_deadline_, now); |
| 372 } | 368 } |
| 373 | 369 |
| 374 idle_period_state_ = new_state; | 370 idle_period_state_ = new_state; |
| 375 idle_period_deadline_ = new_deadline; | 371 idle_period_deadline_ = new_deadline; |
| 376 | 372 |
| 377 // Inform the delegate if we are starting or ending an idle period. | 373 // Inform the delegate if we are starting or ending an idle period. |
| 378 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(old_idle_period_state)) { | 374 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(old_idle_period_state)) { |
| 379 delegate_->OnIdlePeriodStarted(); | 375 delegate_->OnIdlePeriodStarted(); |
| 380 } else if (!IsInIdlePeriod(new_state) && | 376 } else if (!IsInIdlePeriod(new_state) && |
| 381 IsInIdlePeriod(old_idle_period_state)) { | 377 IsInIdlePeriod(old_idle_period_state)) { |
| 382 delegate_->OnIdlePeriodEnded(); | 378 delegate_->OnIdlePeriodEnded(); |
| 383 } | 379 } |
| 384 } | 380 } |
| 385 | 381 |
| 386 void IdleHelper::State::TraceIdleIdleTaskStart() { | 382 void IdleHelper::State::TraceIdleIdleTaskStart() { |
| 387 helper_->CheckOnValidThread(); | 383 helper_->CheckOnValidThread(); |
| 388 | 384 |
| 389 bool is_tracing; | 385 bool is_tracing; |
| 390 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 386 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
| 391 if (is_tracing) { | 387 if (is_tracing) { |
| 392 TraceEventIdlePeriodStateChange( | 388 TraceEventIdlePeriodStateChange(idle_period_state_, true, |
| 393 idle_period_state_, true, idle_period_deadline_, | 389 idle_period_deadline_, |
| 394 base::TimeTicks::Now()); | 390 base::TimeTicks::Now()); |
| 395 } | 391 } |
| 396 } | 392 } |
| 397 | 393 |
| 398 void IdleHelper::State::TraceIdleIdleTaskEnd() { | 394 void IdleHelper::State::TraceIdleIdleTaskEnd() { |
| 399 helper_->CheckOnValidThread(); | 395 helper_->CheckOnValidThread(); |
| 400 | 396 |
| 401 bool is_tracing; | 397 bool is_tracing; |
| 402 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | 398 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); |
| 403 if (is_tracing) { | 399 if (is_tracing) { |
| 404 TraceEventIdlePeriodStateChange( | 400 TraceEventIdlePeriodStateChange(idle_period_state_, false, |
| 405 idle_period_state_, false, idle_period_deadline_, | 401 idle_period_deadline_, |
| 406 base::TimeTicks::Now()); | 402 base::TimeTicks::Now()); |
| 407 } | 403 } |
| 408 } | 404 } |
| 409 | 405 |
| 410 void IdleHelper::State::TraceEventIdlePeriodStateChange( | 406 void IdleHelper::State::TraceEventIdlePeriodStateChange( |
| 411 IdlePeriodState new_state, | 407 IdlePeriodState new_state, |
| 412 bool new_running_idle_task, | 408 bool new_running_idle_task, |
| 413 base::TimeTicks new_deadline, | 409 base::TimeTicks new_deadline, |
| 414 base::TimeTicks now) { | 410 base::TimeTicks now) { |
| 415 TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState", | 411 TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState", |
| 416 "old_state", | 412 "old_state", |
| 417 IdleHelper::IdlePeriodStateToString(idle_period_state_), | 413 IdleHelper::IdlePeriodStateToString(idle_period_state_), |
| 418 "new_state", IdleHelper::IdlePeriodStateToString(new_state)); | 414 "new_state", IdleHelper::IdlePeriodStateToString(new_state)); |
| 419 | 415 |
| 420 if (idle_period_trace_event_started_ && running_idle_task_for_tracing_ && | 416 if (idle_period_trace_event_started_ && running_idle_task_for_tracing_ && |
| 421 !new_running_idle_task) { | 417 !new_running_idle_task) { |
| 422 running_idle_task_for_tracing_ = false; | 418 running_idle_task_for_tracing_ = false; |
| 423 if (!idle_period_deadline_.is_null() && now > idle_period_deadline_) { | 419 if (!idle_period_deadline_.is_null() && now > idle_period_deadline_) { |
| 424 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( | 420 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( |
| 425 tracing_category_, idle_period_tracing_name_, this, | 421 tracing_category_, idle_period_tracing_name_, this, "DeadlineOverrun", |
| 426 "DeadlineOverrun", | 422 std::max(idle_period_deadline_, last_idle_task_trace_time_) |
| 427 std::max(idle_period_deadline_, | 423 .ToInternalValue()); |
| 428 last_idle_task_trace_time_).ToInternalValue()); | |
| 429 } | 424 } |
| 430 } | 425 } |
| 431 | 426 |
| 432 if (IsInIdlePeriod(new_state)) { | 427 if (IsInIdlePeriod(new_state)) { |
| 433 if (!idle_period_trace_event_started_) { | 428 if (!idle_period_trace_event_started_) { |
| 434 idle_period_trace_event_started_ = true; | 429 idle_period_trace_event_started_ = true; |
| 435 TRACE_EVENT_ASYNC_BEGIN1( | 430 TRACE_EVENT_ASYNC_BEGIN1(tracing_category_, idle_period_tracing_name_, |
| 436 tracing_category_, idle_period_tracing_name_, this, | 431 this, "idle_period_length_ms", |
| 437 "idle_period_length_ms", (new_deadline - now).ToInternalValue()); | 432 (new_deadline - now).ToInternalValue()); |
| 438 } | 433 } |
| 439 | 434 |
| 440 if (new_running_idle_task) { | 435 if (new_running_idle_task) { |
| 441 last_idle_task_trace_time_ = now; | 436 last_idle_task_trace_time_ = now; |
| 442 running_idle_task_for_tracing_ = true; | 437 running_idle_task_for_tracing_ = true; |
| 443 TRACE_EVENT_ASYNC_STEP_INTO0( | 438 TRACE_EVENT_ASYNC_STEP_INTO0(tracing_category_, idle_period_tracing_name_, |
| 444 tracing_category_, idle_period_tracing_name_, this, | 439 this, "RunningIdleTask"); |
| 445 "RunningIdleTask"); | |
| 446 } else if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { | 440 } else if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { |
| 447 TRACE_EVENT_ASYNC_STEP_INTO0( | 441 TRACE_EVENT_ASYNC_STEP_INTO0(tracing_category_, idle_period_tracing_name_, |
| 448 tracing_category_, idle_period_tracing_name_, this, | 442 this, "ShortIdlePeriod"); |
| 449 "ShortIdlePeriod"); | |
| 450 } else if (IsInLongIdlePeriod(new_state) && | 443 } else if (IsInLongIdlePeriod(new_state) && |
| 451 new_state != IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | 444 new_state != IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { |
| 452 TRACE_EVENT_ASYNC_STEP_INTO0( | 445 TRACE_EVENT_ASYNC_STEP_INTO0(tracing_category_, idle_period_tracing_name_, |
| 453 tracing_category_, idle_period_tracing_name_, this, | 446 this, "LongIdlePeriod"); |
| 454 "LongIdlePeriod"); | |
| 455 } else if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | 447 } else if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { |
| 456 TRACE_EVENT_ASYNC_STEP_INTO0( | 448 TRACE_EVENT_ASYNC_STEP_INTO0(tracing_category_, idle_period_tracing_name_, |
| 457 tracing_category_, idle_period_tracing_name_, this, | 449 this, "LongIdlePeriodPaused"); |
| 458 "LongIdlePeriodPaused"); | |
| 459 } | 450 } |
| 460 } else if (idle_period_trace_event_started_) { | 451 } else if (idle_period_trace_event_started_) { |
| 461 idle_period_trace_event_started_ = false; | 452 idle_period_trace_event_started_ = false; |
| 462 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this); | 453 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this); |
| 463 } | 454 } |
| 464 } | 455 } |
| 465 | 456 |
| 466 // static | 457 // static |
| 467 const char* IdleHelper::IdlePeriodStateToString( | 458 const char* IdleHelper::IdlePeriodStateToString( |
| 468 IdlePeriodState idle_period_state) { | 459 IdlePeriodState idle_period_state) { |
| 469 switch (idle_period_state) { | 460 switch (idle_period_state) { |
| 470 case IdlePeriodState::NOT_IN_IDLE_PERIOD: | 461 case IdlePeriodState::NOT_IN_IDLE_PERIOD: |
| 471 return "not_in_idle_period"; | 462 return "not_in_idle_period"; |
| 472 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: | 463 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: |
| 473 return "in_short_idle_period"; | 464 return "in_short_idle_period"; |
| 474 case IdlePeriodState::IN_LONG_IDLE_PERIOD: | 465 case IdlePeriodState::IN_LONG_IDLE_PERIOD: |
| 475 return "in_long_idle_period"; | 466 return "in_long_idle_period"; |
| 476 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: | 467 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: |
| 477 return "in_long_idle_period_with_max_deadline"; | 468 return "in_long_idle_period_with_max_deadline"; |
| 478 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: | 469 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: |
| 479 return "in_long_idle_period_paused"; | 470 return "in_long_idle_period_paused"; |
| 480 default: | 471 default: |
| 481 NOTREACHED(); | 472 NOTREACHED(); |
| 482 return nullptr; | 473 return nullptr; |
| 483 } | 474 } |
| 484 } | 475 } |
| 485 | 476 |
| 486 } // namespace scheduler | 477 } // namespace scheduler |
| 478 } // namespace blink |
| OLD | NEW |