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 |