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 "components/scheduler/child/idle_helper.h" |
6 | 6 |
7 #include "base/trace_event/trace_event.h" | 7 #include "base/trace_event/trace_event.h" |
8 #include "base/trace_event/trace_event_argument.h" | 8 #include "base/trace_event/trace_event_argument.h" |
9 #include "components/scheduler/child/scheduler_helper.h" | 9 #include "components/scheduler/child/scheduler_helper.h" |
10 | 10 |
11 namespace scheduler { | 11 namespace scheduler { |
12 | 12 |
13 IdleHelper::IdleHelper( | 13 IdleHelper::IdleHelper( |
14 SchedulerHelper* helper, | 14 SchedulerHelper* helper, |
15 Delegate* delegate, | 15 Delegate* delegate, |
16 size_t idle_queue_index, | 16 size_t idle_queue_index, |
17 const char* tracing_category, | 17 const char* tracing_category, |
18 const char* disabled_by_default_tracing_category, | 18 const char* disabled_by_default_tracing_category, |
19 const char* idle_period_tracing_name, | 19 const char* idle_period_tracing_name, |
20 base::TimeDelta required_quiescence_duration_before_long_idle_period) | 20 base::TimeDelta required_quiescence_duration_before_long_idle_period) |
21 : helper_(helper), | 21 : helper_(helper), |
22 delegate_(delegate), | 22 delegate_(delegate), |
23 idle_queue_index_(idle_queue_index), | 23 idle_queue_index_(idle_queue_index), |
24 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), | 24 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), |
25 quiescence_monitored_task_queue_mask_( | 25 quiescence_monitored_task_queue_mask_( |
26 helper_->GetQuiescenceMonitoredTaskQueueMask() & | 26 helper_->GetQuiescenceMonitoredTaskQueueMask() & |
27 ~(1ull << idle_queue_index_)), | 27 ~(1ull << idle_queue_index_)), |
28 required_quiescence_duration_before_long_idle_period_( | 28 required_quiescence_duration_before_long_idle_period_( |
29 required_quiescence_duration_before_long_idle_period), | 29 required_quiescence_duration_before_long_idle_period), |
30 nestable_events_started_(false), | |
30 tracing_category_(tracing_category), | 31 tracing_category_(tracing_category), |
31 disabled_by_default_tracing_category_( | 32 disabled_by_default_tracing_category_( |
32 disabled_by_default_tracing_category), | 33 disabled_by_default_tracing_category), |
33 idle_period_tracing_name_(idle_period_tracing_name), | 34 idle_period_tracing_name_(idle_period_tracing_name), |
34 weak_factory_(this) { | 35 weak_factory_(this) { |
35 weak_idle_helper_ptr_ = weak_factory_.GetWeakPtr(); | 36 weak_idle_helper_ptr_ = weak_factory_.GetWeakPtr(); |
36 end_idle_period_closure_.Reset( | |
37 base::Bind(&IdleHelper::EndIdlePeriod, weak_idle_helper_ptr_)); | |
38 enable_next_long_idle_period_closure_.Reset( | 37 enable_next_long_idle_period_closure_.Reset( |
39 base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); | 38 base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); |
40 enable_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind( | |
41 &IdleHelper::EnableLongIdlePeriodAfterWakeup, weak_idle_helper_ptr_)); | |
42 | 39 |
43 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( | 40 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( |
44 helper_->TaskRunnerForQueue(idle_queue_index_), | 41 helper_->TaskRunnerForQueue(idle_queue_index_), |
45 helper_->ControlAfterWakeUpTaskRunner(), | 42 helper_->ControlAfterWakeUpTaskRunner(), |
46 base::Bind(&IdleHelper::CurrentIdleTaskDeadlineCallback, | 43 this, |
47 weak_idle_helper_ptr_), | |
48 tracing_category)); | 44 tracing_category)); |
49 | 45 |
50 helper_->DisableQueue(idle_queue_index_); | 46 helper_->DisableQueue(idle_queue_index_); |
51 helper_->SetPumpPolicy(idle_queue_index_, | 47 helper_->SetPumpPolicy(idle_queue_index_, |
52 TaskQueueManager::PumpPolicy::MANUAL); | 48 TaskQueueManager::PumpPolicy::MANUAL); |
49 | |
50 helper_->AddTaskObserver(this); | |
53 } | 51 } |
54 | 52 |
55 IdleHelper::~IdleHelper() { | 53 IdleHelper::~IdleHelper() { |
56 } | 54 } |
57 | 55 |
58 IdleHelper::Delegate::Delegate() { | 56 IdleHelper::Delegate::Delegate() { |
59 } | 57 } |
60 | 58 |
61 IdleHelper::Delegate::~Delegate() { | 59 IdleHelper::Delegate::~Delegate() { |
62 } | 60 } |
63 | 61 |
64 scoped_refptr<SingleThreadIdleTaskRunner> IdleHelper::IdleTaskRunner() { | 62 scoped_refptr<SingleThreadIdleTaskRunner> IdleHelper::IdleTaskRunner() { |
65 helper_->CheckOnValidThread(); | 63 helper_->CheckOnValidThread(); |
66 return idle_task_runner_; | 64 return idle_task_runner_; |
67 } | 65 } |
68 | 66 |
69 void IdleHelper::CurrentIdleTaskDeadlineCallback( | |
70 base::TimeTicks* deadline_out) const { | |
71 helper_->CheckOnValidThread(); | |
72 *deadline_out = idle_period_deadline_; | |
73 } | |
74 | |
75 IdleHelper::IdlePeriodState IdleHelper::ComputeNewLongIdlePeriodState( | 67 IdleHelper::IdlePeriodState IdleHelper::ComputeNewLongIdlePeriodState( |
76 const base::TimeTicks now, | 68 const base::TimeTicks now, |
77 base::TimeDelta* next_long_idle_period_delay_out) { | 69 base::TimeDelta* next_long_idle_period_delay_out) { |
78 helper_->CheckOnValidThread(); | 70 helper_->CheckOnValidThread(); |
79 | 71 |
80 if (!delegate_->CanEnterLongIdlePeriod(now, | 72 if (!delegate_->CanEnterLongIdlePeriod(now, |
81 next_long_idle_period_delay_out)) { | 73 next_long_idle_period_delay_out)) { |
82 return IdlePeriodState::NOT_IN_IDLE_PERIOD; | 74 return IdlePeriodState::NOT_IN_IDLE_PERIOD; |
83 } | 75 } |
84 | 76 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 task_queues_run_since_last_check_bitmap); | 119 task_queues_run_since_last_check_bitmap); |
128 | 120 |
129 // If anything was run on the queues we care about, then we're not quiescent | 121 // If anything was run on the queues we care about, then we're not quiescent |
130 // and we should wait. | 122 // and we should wait. |
131 return task_queues_run_since_last_check_bitmap != 0; | 123 return task_queues_run_since_last_check_bitmap != 0; |
132 } | 124 } |
133 | 125 |
134 void IdleHelper::EnableLongIdlePeriod() { | 126 void IdleHelper::EnableLongIdlePeriod() { |
135 TRACE_EVENT0(disabled_by_default_tracing_category_, "EnableLongIdlePeriod"); | 127 TRACE_EVENT0(disabled_by_default_tracing_category_, "EnableLongIdlePeriod"); |
136 helper_->CheckOnValidThread(); | 128 helper_->CheckOnValidThread(); |
129 if (helper_->IsShutdown()) | |
130 return; | |
137 | 131 |
138 // End any previous idle period. | 132 // End any previous idle period. |
139 EndIdlePeriod(); | 133 EndIdlePeriod(); |
140 | 134 |
141 if (ShouldWaitForQuiescence()) { | 135 if (ShouldWaitForQuiescence()) { |
142 helper_->ControlTaskRunner()->PostDelayedTask( | 136 helper_->ControlTaskRunner()->PostDelayedTask( |
143 FROM_HERE, enable_next_long_idle_period_closure_.callback(), | 137 FROM_HERE, enable_next_long_idle_period_closure_.callback(), |
144 required_quiescence_duration_before_long_idle_period_); | 138 required_quiescence_duration_before_long_idle_period_); |
145 delegate_->IsNotQuiescent(); | 139 delegate_->IsNotQuiescent(); |
146 return; | 140 return; |
147 } | 141 } |
148 | 142 |
149 base::TimeTicks now(helper_->Now()); | 143 base::TimeTicks now(helper_->Now()); |
150 base::TimeDelta next_long_idle_period_delay; | 144 base::TimeDelta next_long_idle_period_delay; |
151 IdlePeriodState new_idle_period_state = | 145 IdlePeriodState new_idle_period_state = |
152 ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay); | 146 ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay); |
153 if (IsInIdlePeriod(new_idle_period_state)) { | 147 if (IsInIdlePeriod(new_idle_period_state)) { |
154 StartIdlePeriod(new_idle_period_state, now, | 148 StartIdlePeriod(new_idle_period_state, now, |
155 now + next_long_idle_period_delay, false); | 149 now + next_long_idle_period_delay); |
156 } | |
157 | |
158 if (helper_->IsQueueEmpty(idle_queue_index_)) { | |
159 // If there are no current idle tasks then post the call to initiate the | |
160 // next idle for execution after wakeup (at which point after-wakeup idle | |
161 // tasks might be eligible to run or more idle tasks posted). | |
162 helper_->ControlAfterWakeUpTaskRunner()->PostDelayedTask( | |
163 FROM_HERE, | |
164 enable_next_long_idle_period_after_wakeup_closure_.callback(), | |
165 next_long_idle_period_delay); | |
166 } else { | 150 } else { |
167 // Otherwise post on the normal control task queue. | 151 // Otherwise wait for the next long idle period delay before trying again. |
168 helper_->ControlTaskRunner()->PostDelayedTask( | 152 helper_->ControlTaskRunner()->PostDelayedTask( |
169 FROM_HERE, enable_next_long_idle_period_closure_.callback(), | 153 FROM_HERE, enable_next_long_idle_period_closure_.callback(), |
170 next_long_idle_period_delay); | 154 next_long_idle_period_delay); |
171 } | 155 } |
172 } | 156 } |
173 | 157 |
174 void IdleHelper::EnableLongIdlePeriodAfterWakeup() { | |
175 TRACE_EVENT0(disabled_by_default_tracing_category_, | |
176 "EnableLongIdlePeriodAfterWakeup"); | |
177 helper_->CheckOnValidThread(); | |
178 | |
179 if (IsInIdlePeriod(idle_period_state_)) { | |
180 // Since we were asleep until now, end the async idle period trace event at | |
181 // the time when it would have ended were we awake. | |
182 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( | |
183 tracing_category_, idle_period_tracing_name_, this, | |
184 std::min(idle_period_deadline_, helper_->Now()).ToInternalValue()); | |
185 idle_period_state_ = IdlePeriodState::ENDING_LONG_IDLE_PERIOD; | |
186 EndIdlePeriod(); | |
187 } | |
188 | |
189 // Post a task to initiate the next long idle period rather than calling it | |
190 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued | |
191 // on the idle task queue before the next idle period starts so they are | |
192 // eligible to be run during the new idle period. | |
193 helper_->ControlTaskRunner()->PostTask( | |
194 FROM_HERE, enable_next_long_idle_period_closure_.callback()); | |
195 } | |
196 | |
197 void IdleHelper::StartIdlePeriod(IdlePeriodState new_state, | 158 void IdleHelper::StartIdlePeriod(IdlePeriodState new_state, |
198 base::TimeTicks now, | 159 base::TimeTicks now, |
199 base::TimeTicks idle_period_deadline, | 160 base::TimeTicks idle_period_deadline) { |
200 bool post_end_idle_period) { | |
201 DCHECK_GT(idle_period_deadline, now); | 161 DCHECK_GT(idle_period_deadline, now); |
202 TRACE_EVENT_ASYNC_BEGIN0(tracing_category_, idle_period_tracing_name_, this); | |
203 helper_->CheckOnValidThread(); | 162 helper_->CheckOnValidThread(); |
204 DCHECK(IsInIdlePeriod(new_state)); | 163 DCHECK(IsInIdlePeriod(new_state)); |
164 TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod"); | |
205 | 165 |
206 helper_->EnableQueue(idle_queue_index_, | 166 helper_->EnableQueue(idle_queue_index_, |
207 PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY); | 167 PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY); |
208 helper_->PumpQueue(idle_queue_index_); | 168 helper_->PumpQueue(idle_queue_index_); |
209 idle_period_state_ = new_state; | |
210 | 169 |
211 idle_period_deadline_ = idle_period_deadline; | 170 SetIdlePeriodState(new_state, idle_period_deadline, now); |
212 if (post_end_idle_period) { | |
213 helper_->ControlTaskRunner()->PostDelayedTask( | |
214 FROM_HERE, end_idle_period_closure_.callback(), | |
215 idle_period_deadline_ - now); | |
216 } | |
217 } | 171 } |
218 | 172 |
219 void IdleHelper::EndIdlePeriod() { | 173 void IdleHelper::EndIdlePeriod() { |
220 helper_->CheckOnValidThread(); | 174 helper_->CheckOnValidThread(); |
175 TRACE_EVENT0(disabled_by_default_tracing_category_, "EndIdlePeriod"); | |
221 | 176 |
222 end_idle_period_closure_.Cancel(); | |
223 enable_next_long_idle_period_closure_.Cancel(); | 177 enable_next_long_idle_period_closure_.Cancel(); |
224 enable_next_long_idle_period_after_wakeup_closure_.Cancel(); | |
225 | 178 |
226 // If we weren't already within an idle period then early-out. | 179 // If we weren't already within an idle period then early-out. |
227 if (!IsInIdlePeriod(idle_period_state_)) | 180 if (!IsInIdlePeriod(idle_period_state_)) |
228 return; | 181 return; |
229 | 182 |
230 // If we are in the ENDING_LONG_IDLE_PERIOD state we have already logged the | |
231 // trace event. | |
232 if (idle_period_state_ != IdlePeriodState::ENDING_LONG_IDLE_PERIOD) { | |
233 bool is_tracing; | |
234 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | |
235 if (is_tracing && !idle_period_deadline_.is_null() && | |
236 helper_->Now() > idle_period_deadline_) { | |
237 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( | |
238 tracing_category_, idle_period_tracing_name_, this, "DeadlineOverrun", | |
239 idle_period_deadline_.ToInternalValue()); | |
240 } | |
241 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this); | |
242 } | |
243 | |
244 helper_->DisableQueue(idle_queue_index_); | 183 helper_->DisableQueue(idle_queue_index_); |
245 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD; | 184 SetIdlePeriodState(IdlePeriodState::NOT_IN_IDLE_PERIOD, |
185 base::TimeTicks(), base::TimeTicks()); | |
246 idle_period_deadline_ = base::TimeTicks(); | 186 idle_period_deadline_ = base::TimeTicks(); |
247 } | 187 } |
248 | 188 |
189 void IdleHelper::WillProcessTask(const base::PendingTask& pending_task) { | |
190 } | |
191 | |
192 void IdleHelper::DidProcessTask(const base::PendingTask& pending_task) { | |
193 helper_->CheckOnValidThread(); | |
194 TRACE_EVENT0(disabled_by_default_tracing_category_, "DidProcessTask"); | |
195 if (IsInIdlePeriod(idle_period_state_) && | |
196 idle_period_state_ != IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED && | |
197 helper_->Now() >= idle_period_deadline_) { | |
198 // If the idle period has now been reached, either end the idle period or | |
Sami
2015/05/26 13:35:41
"idle period deadline"?
rmcilroy
2015/05/27 11:58:36
Done.
| |
199 // trigger a new long-idle period. | |
200 if (IsInLongIdlePeriod(idle_period_state_)) { | |
201 EnableLongIdlePeriod(); | |
202 } else { | |
203 DCHECK(IdlePeriodState::IN_SHORT_IDLE_PERIOD == idle_period_state_); | |
204 EndIdlePeriod(); | |
205 } | |
206 } | |
207 } | |
208 | |
209 void IdleHelper::CheckLongIdlePeriodSentinel() { | |
210 helper_->CheckOnValidThread(); | |
211 DCHECK(IsInLongIdlePeriod(idle_period_state_)); | |
212 TRACE_EVENT0(disabled_by_default_tracing_category_, | |
213 "CheckLongIdlePeriodSentinel"); | |
214 | |
215 if (helper_->IsQueueEmpty(idle_queue_index_)) { | |
Sami
2015/05/26 13:35:41
Optimization-ocd-nit: we could combine IsQueueEmpt
rmcilroy
2015/05/27 11:58:36
Ack. I'll make this change on the preceeding CL an
rmcilroy
2015/05/27 19:17:05
Done in latest patchset.
| |
216 // If there are no more idle tasks then pause long idle period ticks until a | |
217 // new idle task is posted. | |
218 SetIdlePeriodState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED, | |
219 idle_period_deadline_, | |
220 base::TimeTicks()); | |
221 } else if (helper_->QueueNeedsPumped(idle_queue_index_)) { | |
222 // If there is still idle work to do then just start the next idle period. | |
223 base::TimeDelta next_long_idle_period_delay; | |
224 if (idle_period_state_ == | |
225 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE) { | |
226 // If we are in a max deadline long idle period then start the next | |
227 // idle period immediately. | |
228 next_long_idle_period_delay = base::TimeDelta(); | |
229 } else { | |
230 // Otherwise ensure that we kick the scheduler at the right time to | |
231 // initiate the next idle period. | |
232 next_long_idle_period_delay = idle_period_deadline_ - helper_->Now(); | |
Sami
2015/05/26 13:35:41
Should we clamp this to zero to avoid random DCHEC
rmcilroy
2015/05/27 11:58:36
Good point! Done.
| |
233 } | |
234 helper_->ControlTaskRunner()->PostDelayedTask(FROM_HERE, | |
235 enable_next_long_idle_period_closure_.callback(), | |
236 next_long_idle_period_delay); | |
237 } | |
238 } | |
239 | |
240 void IdleHelper::CurrentIdleTaskDeadlineCallback( | |
241 base::TimeTicks* deadline_out) const { | |
242 helper_->CheckOnValidThread(); | |
243 *deadline_out = idle_period_deadline_; | |
244 } | |
245 | |
246 | |
247 void IdleHelper::OnIdleTaskPosted() { | |
248 helper_->CheckOnValidThread(); | |
Sami
2015/05/26 13:35:40
This can be running on any thread, right?
rmcilroy
2015/05/27 11:58:36
Yes, thanks. Done.
Sami
2015/05/27 12:11:56
Did you mean to add some locking/posting here?-)
rmcilroy
2015/05/27 19:17:05
Opps, added a comment about this then forgot about
| |
249 if (idle_period_state_ == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | |
250 // Restart long idle period ticks. | |
251 enable_next_long_idle_period_closure_.Cancel(); | |
252 helper_->ControlTaskRunner()->PostTask(FROM_HERE, | |
253 enable_next_long_idle_period_closure_.callback()); | |
254 } | |
255 } | |
256 | |
257 void IdleHelper::OnWillRunIdleTask(base::TimeTicks* deadline_out) const { | |
258 helper_->CheckOnValidThread(); | |
259 //DCHECK(IsInIdlePeriod(idle_period_state_)); | |
Sami
2015/05/26 13:35:41
Uncomment/remove?
rmcilroy
2015/05/27 11:58:36
Uncommented
| |
260 bool is_tracing; | |
261 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | |
262 if (is_tracing && nestable_events_started_) { | |
263 last_traced_start_running_idle_task_ = helper_->Now(); | |
Sami
2015/05/26 13:35:40
I believe we should use NowFromSystemTraceTime() t
rmcilroy
2015/05/27 11:58:36
Done, although we later pass "std::max(idle_period
Sami
2015/05/27 12:11:56
I think we should. The two timebases aren't compat
rmcilroy
2015/05/27 19:17:05
Ok, good to know. Done.
| |
264 TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( | |
265 tracing_category_, "RunningIdleTask", this, | |
266 last_traced_start_running_idle_task_.ToInternalValue()); | |
267 } | |
268 CurrentIdleTaskDeadlineCallback(deadline_out); | |
Sami
2015/05/26 13:35:41
Could we just replace this with a simple assigment
rmcilroy
2015/05/27 11:58:36
I kept the method for tests. Removed "Callback".
| |
269 } | |
270 | |
271 void IdleHelper::OnDidRunIdleTask() { | |
272 helper_->CheckOnValidThread(); | |
273 DCHECK(IsInIdlePeriod(idle_period_state_)); | |
274 bool is_tracing; | |
275 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | |
276 if (is_tracing && nestable_events_started_) { | |
277 if (!idle_period_deadline_.is_null() && | |
278 helper_->Now() > idle_period_deadline_) { | |
279 TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( | |
280 tracing_category_,"DeadlineOverrun", this, | |
281 std::max(idle_period_deadline_, last_traced_start_running_idle_task_) | |
282 .ToInternalValue()); | |
283 TRACE_EVENT_NESTABLE_ASYNC_END0( | |
284 tracing_category_,"DeadlineOverrun", this); | |
285 } | |
286 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "RunningIdleTask", this); | |
287 } | |
288 | |
289 if (IsInLongIdlePeriod(idle_period_state_)) { | |
290 CheckLongIdlePeriodSentinel(); | |
Sami
2015/05/26 13:35:40
nit: It's not clear what "sentinel" refers to here
rmcilroy
2015/05/27 11:58:36
Yeah, this was originally a sentinal task posted o
| |
291 } | |
292 } | |
293 | |
249 // static | 294 // static |
250 bool IdleHelper::IsInIdlePeriod(IdlePeriodState state) { | 295 bool IdleHelper::IsInIdlePeriod(IdlePeriodState state) { |
251 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD; | 296 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD; |
252 } | 297 } |
253 | 298 |
299 // static | |
300 bool IdleHelper::IsInLongIdlePeriod(IdlePeriodState state) { | |
301 return state == IdlePeriodState::IN_LONG_IDLE_PERIOD || | |
302 state == IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE || | |
303 state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED; | |
304 } | |
305 | |
306 void IdleHelper::SetIdlePeriodState(IdlePeriodState new_state, | |
307 base::TimeTicks new_deadline, | |
308 base::TimeTicks optional_now) { | |
309 helper_->CheckOnValidThread(); | |
310 if (new_state == idle_period_state_) return; | |
Sami
2015/05/26 13:35:40
Should we DCHECK that the deadline didn't change?
rmcilroy
2015/05/27 11:58:36
Done.
| |
311 | |
312 bool is_tracing; | |
313 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); | |
314 if (is_tracing) { | |
315 TraceEventIdlePeriodStateChange(new_state, new_deadline, optional_now); | |
316 } | |
317 | |
318 idle_period_state_ = new_state; | |
319 idle_period_deadline_ = new_deadline; | |
320 } | |
321 | |
254 bool IdleHelper::CanExceedIdleDeadlineIfRequired() const { | 322 bool IdleHelper::CanExceedIdleDeadlineIfRequired() const { |
255 TRACE_EVENT0(tracing_category_, "CanExceedIdleDeadlineIfRequired"); | 323 TRACE_EVENT0(tracing_category_, "CanExceedIdleDeadlineIfRequired"); |
256 helper_->CheckOnValidThread(); | 324 helper_->CheckOnValidThread(); |
257 return idle_period_state_ == | 325 return idle_period_state_ == |
258 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE; | 326 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE; |
259 } | 327 } |
260 | 328 |
261 IdleHelper::IdlePeriodState IdleHelper::SchedulerIdlePeriodState() const { | 329 IdleHelper::IdlePeriodState IdleHelper::SchedulerIdlePeriodState() const { |
262 return idle_period_state_; | 330 return idle_period_state_; |
263 } | 331 } |
264 | 332 |
333 void IdleHelper::TraceEventIdlePeriodStateChange( | |
334 IdlePeriodState new_state, | |
335 base::TimeTicks new_deadline, | |
336 base::TimeTicks optional_now) const { | |
337 TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState", | |
338 "old_state", IdleHelper::IdlePeriodStateToString(idle_period_state_), | |
339 "new_state", IdleHelper::IdlePeriodStateToString(new_state)); | |
340 if (nestable_events_started_) { | |
341 // End async tracing events for the state we are leaving. | |
342 if (idle_period_state_ == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | |
343 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
Sami
2015/05/26 13:35:40
Would this work better using the non-nestable STEP
rmcilroy
2015/05/27 11:58:36
Apparently the non-nestable STEP_INTO variants are
Sami
2015/05/27 12:11:56
Yeah thanks I didn't realize they were deprecated.
| |
344 "LongIdlePeriodPaused", | |
345 this); | |
346 } | |
347 if (IsInLongIdlePeriod(idle_period_state_) && | |
348 !IsInLongIdlePeriod(new_state)) { | |
349 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
350 "LongIdlePeriod", | |
351 this); | |
352 } | |
353 if (idle_period_state_ == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { | |
354 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
355 "ShortIdlePeriod", | |
356 this); | |
357 } | |
358 if (IsInIdlePeriod(idle_period_state_) && !IsInLongIdlePeriod(new_state)) { | |
359 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
360 idle_period_tracing_name_, | |
361 this); | |
362 nestable_events_started_ = false; | |
363 } | |
364 } | |
365 | |
366 // Start async tracing events for the state we are entering. | |
367 if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(idle_period_state_)) { | |
368 if (optional_now.is_null()) | |
369 optional_now = helper_->Now(); | |
370 nestable_events_started_ = | |
Sami
2015/05/26 13:35:40
Weird newline here.
rmcilroy
2015/05/27 11:58:36
Done.
| |
371 true; | |
372 TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(tracing_category_, | |
373 idle_period_tracing_name_, | |
374 this, | |
375 "idle_period_length_ms", | |
376 (new_deadline - optional_now).ToInternalValue()); | |
377 } | |
378 if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) { | |
379 TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, | |
380 "ShortIdlePeriod", | |
381 this); | |
382 } | |
383 if (IsInLongIdlePeriod(new_state) && !IsInIdlePeriod(idle_period_state_)) { | |
384 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, | |
385 "LongIdlePeriod", | |
386 this); | |
387 } | |
388 if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) { | |
389 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, | |
390 "LongIdlePeriodPaused", | |
391 this); | |
392 } | |
393 } | |
394 | |
265 // static | 395 // static |
266 const char* IdleHelper::IdlePeriodStateToString( | 396 const char* IdleHelper::IdlePeriodStateToString( |
267 IdlePeriodState idle_period_state) { | 397 IdlePeriodState idle_period_state) { |
268 switch (idle_period_state) { | 398 switch (idle_period_state) { |
269 case IdlePeriodState::NOT_IN_IDLE_PERIOD: | 399 case IdlePeriodState::NOT_IN_IDLE_PERIOD: |
270 return "not_in_idle_period"; | 400 return "not_in_idle_period"; |
271 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: | 401 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: |
272 return "in_short_idle_period"; | 402 return "in_short_idle_period"; |
273 case IdlePeriodState::IN_LONG_IDLE_PERIOD: | 403 case IdlePeriodState::IN_LONG_IDLE_PERIOD: |
274 return "in_long_idle_period"; | 404 return "in_long_idle_period"; |
275 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: | 405 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: |
276 return "in_long_idle_period_with_max_deadline"; | 406 return "in_long_idle_period_with_max_deadline"; |
277 case IdlePeriodState::ENDING_LONG_IDLE_PERIOD: | 407 case IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED: |
278 return "ending_long_idle_period"; | 408 return "in_long_idle_period_paused"; |
279 default: | 409 default: |
280 NOTREACHED(); | 410 NOTREACHED(); |
281 return nullptr; | 411 return nullptr; |
282 } | 412 } |
283 } | 413 } |
284 | 414 |
285 } // namespace scheduler | 415 } // namespace scheduler |
OLD | NEW |