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