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 |