| 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 "platform/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 "platform/scheduler/base/real_time_domain.h" | 10 #include "platform/scheduler/base/real_time_domain.h" |
| 11 #include "public/platform/scheduler/base/task_queue.h" | 11 #include "public/platform/scheduler/base/task_queue.h" |
| 12 #include "platform/scheduler/base/task_queue_manager.h" | 12 #include "platform/scheduler/base/task_queue_manager.h" |
| 13 #include "platform/scheduler/child/scheduler_helper.h" | 13 #include "platform/scheduler/child/scheduler_helper.h" |
| 14 #include "platform/scheduler/child/scheduler_tqm_delegate.h" | 14 #include "platform/scheduler/child/scheduler_tqm_delegate.h" |
| 15 | 15 |
| 16 namespace blink { | 16 namespace blink { |
| 17 namespace scheduler { | 17 namespace scheduler { |
| 18 | 18 |
| 19 IdleHelper::IdleHelper( | 19 IdleHelper::IdleHelper( |
| 20 SchedulerHelper* helper, | 20 SchedulerHelper* helper, |
| 21 Delegate* delegate, | 21 Delegate* delegate, |
| 22 const char* tracing_category, | 22 const char* tracing_category, |
| 23 const char* disabled_by_default_tracing_category, | 23 const char* disabled_by_default_tracing_category, |
| 24 const char* idle_period_tracing_name, | 24 const char* idle_period_tracing_name, |
| 25 base::TimeDelta required_quiescence_duration_before_long_idle_period) | 25 base::TimeDelta required_quiescence_duration_before_long_idle_period) |
| 26 : helper_(helper), | 26 : helper_(helper), |
| 27 delegate_(delegate), | 27 delegate_(delegate), |
| 28 idle_queue_( | 28 idle_queue_(helper_->NewTaskQueue(TaskQueue::Spec("idle_tq"))), |
| 29 helper_->NewTaskQueue(TaskQueue::Spec("idle_tq").SetPumpPolicy( | |
| 30 TaskQueue::PumpPolicy::MANUAL))), | |
| 31 state_(helper, | 29 state_(helper, |
| 32 delegate, | 30 delegate, |
| 33 tracing_category, | 31 tracing_category, |
| 34 disabled_by_default_tracing_category, | 32 disabled_by_default_tracing_category, |
| 35 idle_period_tracing_name), | 33 idle_period_tracing_name), |
| 36 required_quiescence_duration_before_long_idle_period_( | 34 required_quiescence_duration_before_long_idle_period_( |
| 37 required_quiescence_duration_before_long_idle_period), | 35 required_quiescence_duration_before_long_idle_period), |
| 38 disabled_by_default_tracing_category_( | 36 disabled_by_default_tracing_category_( |
| 39 disabled_by_default_tracing_category), | 37 disabled_by_default_tracing_category), |
| 40 weak_factory_(this) { | 38 weak_factory_(this) { |
| 41 weak_idle_helper_ptr_ = weak_factory_.GetWeakPtr(); | 39 weak_idle_helper_ptr_ = weak_factory_.GetWeakPtr(); |
| 42 enable_next_long_idle_period_closure_.Reset( | 40 enable_next_long_idle_period_closure_.Reset( |
| 43 base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); | 41 base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); |
| 44 on_idle_task_posted_closure_.Reset(base::Bind( | 42 on_idle_task_posted_closure_.Reset(base::Bind( |
| 45 &IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_)); | 43 &IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_)); |
| 46 | 44 |
| 47 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( | 45 idle_task_runner_ = make_scoped_refptr( |
| 48 idle_queue_, helper_->ControlAfterWakeUpTaskRunner(), this, | 46 new SingleThreadIdleTaskRunner(idle_queue_, this, tracing_category)); |
| 49 tracing_category)); | |
| 50 | 47 |
| 51 idle_queue_->SetQueueEnabled(false); | 48 idle_queue_->SetQueueEnabled(false); |
| 52 idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); | 49 idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); |
| 53 | 50 |
| 54 helper_->AddTaskObserver(this); | 51 helper_->AddTaskObserver(this); |
| 55 } | 52 } |
| 56 | 53 |
| 57 IdleHelper::~IdleHelper() { | 54 IdleHelper::~IdleHelper() { |
| 58 helper_->RemoveTaskObserver(this); | 55 helper_->RemoveTaskObserver(this); |
| 59 } | 56 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 105 } |
| 109 } | 106 } |
| 110 | 107 |
| 111 bool IdleHelper::ShouldWaitForQuiescence() { | 108 bool IdleHelper::ShouldWaitForQuiescence() { |
| 112 helper_->CheckOnValidThread(); | 109 helper_->CheckOnValidThread(); |
| 113 | 110 |
| 114 if (helper_->IsShutdown()) | 111 if (helper_->IsShutdown()) |
| 115 return false; | 112 return false; |
| 116 | 113 |
| 117 if (required_quiescence_duration_before_long_idle_period_ == | 114 if (required_quiescence_duration_before_long_idle_period_ == |
| 118 base::TimeDelta()) | 115 base::TimeDelta()) { |
| 119 return false; | 116 return false; |
| 117 } |
| 120 | 118 |
| 121 bool system_is_quiescent = helper_->GetAndClearSystemIsQuiescentBit(); | 119 bool system_is_quiescent = helper_->GetAndClearSystemIsQuiescentBit(); |
| 122 TRACE_EVENT1(disabled_by_default_tracing_category_, "ShouldWaitForQuiescence", | 120 TRACE_EVENT1(disabled_by_default_tracing_category_, "ShouldWaitForQuiescence", |
| 123 "system_is_quiescent", system_is_quiescent); | 121 "system_is_quiescent", system_is_quiescent); |
| 124 return !system_is_quiescent; | 122 return !system_is_quiescent; |
| 125 } | 123 } |
| 126 | 124 |
| 127 void IdleHelper::EnableLongIdlePeriod() { | 125 void IdleHelper::EnableLongIdlePeriod() { |
| 128 TRACE_EVENT0(disabled_by_default_tracing_category_, "EnableLongIdlePeriod"); | 126 TRACE_EVENT0(disabled_by_default_tracing_category_, "EnableLongIdlePeriod"); |
| 129 helper_->CheckOnValidThread(); | 127 helper_->CheckOnValidThread(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) { | 166 base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) { |
| 169 TRACE_EVENT1(disabled_by_default_tracing_category_, | 167 TRACE_EVENT1(disabled_by_default_tracing_category_, |
| 170 "NotStartingIdlePeriodBecauseDeadlineIsTooClose", | 168 "NotStartingIdlePeriodBecauseDeadlineIsTooClose", |
| 171 "idle_period_duration_ms", | 169 "idle_period_duration_ms", |
| 172 idle_period_duration.InMillisecondsF()); | 170 idle_period_duration.InMillisecondsF()); |
| 173 return; | 171 return; |
| 174 } | 172 } |
| 175 | 173 |
| 176 TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod"); | 174 TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod"); |
| 177 idle_queue_->SetQueueEnabled(true); | 175 idle_queue_->SetQueueEnabled(true); |
| 178 LazyNow lazy_now(now); | 176 // Use a fence to make sure any idle tasks posted after this point do not run |
| 179 idle_queue_->PumpQueue(&lazy_now, true); | 177 // until the next idle period. |
| 178 idle_queue_->InsertFence(); |
| 180 | 179 |
| 181 state_.UpdateState(new_state, idle_period_deadline, now); | 180 state_.UpdateState(new_state, idle_period_deadline, now); |
| 182 } | 181 } |
| 183 | 182 |
| 184 void IdleHelper::EndIdlePeriod() { | 183 void IdleHelper::EndIdlePeriod() { |
| 185 helper_->CheckOnValidThread(); | 184 helper_->CheckOnValidThread(); |
| 186 TRACE_EVENT0(disabled_by_default_tracing_category_, "EndIdlePeriod"); | 185 TRACE_EVENT0(disabled_by_default_tracing_category_, "EndIdlePeriod"); |
| 187 | 186 |
| 188 enable_next_long_idle_period_closure_.Cancel(); | 187 enable_next_long_idle_period_closure_.Cancel(); |
| 189 on_idle_task_posted_closure_.Cancel(); | 188 on_idle_task_posted_closure_.Cancel(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 helper_->CheckOnValidThread(); | 222 helper_->CheckOnValidThread(); |
| 224 DCHECK(IsInLongIdlePeriod(state_.idle_period_state())); | 223 DCHECK(IsInLongIdlePeriod(state_.idle_period_state())); |
| 225 TRACE_EVENT0(disabled_by_default_tracing_category_, | 224 TRACE_EVENT0(disabled_by_default_tracing_category_, |
| 226 "UpdateLongIdlePeriodStateAfterIdleTask"); | 225 "UpdateLongIdlePeriodStateAfterIdleTask"); |
| 227 | 226 |
| 228 if (!idle_queue_->HasPendingImmediateWork()) { | 227 if (!idle_queue_->HasPendingImmediateWork()) { |
| 229 // If there are no more idle tasks then pause long idle period ticks until a | 228 // If there are no more idle tasks then pause long idle period ticks until a |
| 230 // new idle task is posted. | 229 // new idle task is posted. |
| 231 state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED, | 230 state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED, |
| 232 state_.idle_period_deadline(), base::TimeTicks()); | 231 state_.idle_period_deadline(), base::TimeTicks()); |
| 233 } else if (idle_queue_->NeedsPumping()) { | 232 } else if (idle_queue_->BlockedByFence()) { |
| 234 // If there is still idle work to do then just start the next idle period. | 233 // If there is still idle work to do then just start the next idle period. |
| 235 base::TimeDelta next_long_idle_period_delay; | 234 base::TimeDelta next_long_idle_period_delay; |
| 236 if (state_.idle_period_state() == | 235 if (state_.idle_period_state() == |
| 237 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE) { | 236 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE) { |
| 238 // If we are in a max deadline long idle period then start the next | 237 // If we are in a max deadline long idle period then start the next |
| 239 // idle period immediately. | 238 // idle period immediately. |
| 240 next_long_idle_period_delay = base::TimeDelta(); | 239 next_long_idle_period_delay = base::TimeDelta(); |
| 241 } else { | 240 } else { |
| 242 // Otherwise ensure that we kick the scheduler at the right time to | 241 // Otherwise ensure that we kick the scheduler at the right time to |
| 243 // initiate the next idle period. | 242 // initiate the next idle period. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: | 468 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: |
| 470 return "in_long_idle_period_paused"; | 469 return "in_long_idle_period_paused"; |
| 471 default: | 470 default: |
| 472 NOTREACHED(); | 471 NOTREACHED(); |
| 473 return nullptr; | 472 return nullptr; |
| 474 } | 473 } |
| 475 } | 474 } |
| 476 | 475 |
| 477 } // namespace scheduler | 476 } // namespace scheduler |
| 478 } // namespace blink | 477 } // namespace blink |
| OLD | NEW |