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/renderer/task_queue_throttler.h" | 5 #include "platform/scheduler/renderer/task_queue_throttler.h" |
6 | 6 |
7 #include <cstdint> | 7 #include <cstdint> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 if (!task_queue->IsEmpty()) { | 135 if (!task_queue->IsEmpty()) { |
136 LazyNow lazy_now(tick_clock_); | 136 LazyNow lazy_now(tick_clock_); |
137 OnQueueNextWakeUpChanged(task_queue, | 137 OnQueueNextWakeUpChanged(task_queue, |
138 NextTaskRunTime(&lazy_now, task_queue).value()); | 138 NextTaskRunTime(&lazy_now, task_queue).value()); |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { | 142 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { |
143 TaskQueueMap::iterator iter = queue_details_.find(task_queue); | 143 TaskQueueMap::iterator iter = queue_details_.find(task_queue); |
144 | 144 |
145 if (iter == queue_details_.end() || | 145 if (iter == queue_details_.end()) |
146 --iter->second.throttling_ref_count != 0) { | |
147 return; | 146 return; |
148 } | 147 if (iter->second.throttling_ref_count == 0) |
148 return; | |
149 if (--iter->second.throttling_ref_count != 0) | |
150 return; | |
149 | 151 |
150 TRACE_EVENT1("renderer.scheduler", "TaskQueueThrottler_TaskQueueUnthrottled", | 152 TRACE_EVENT1("renderer.scheduler", "TaskQueueThrottler_TaskQueueUnthrottled", |
151 "task_queue", task_queue); | 153 "task_queue", task_queue); |
152 | 154 |
153 task_queue->SetObserver(nullptr); | 155 task_queue->SetObserver(nullptr); |
154 | 156 |
155 MaybeDeleteQueueMetadata(iter); | 157 MaybeDeleteQueueMetadata(iter); |
156 | 158 |
157 if (!allow_throttling_) | 159 if (!allow_throttling_) |
158 return; | 160 return; |
(...skipping 10 matching lines...) Expand all Loading... | |
169 if (find_it == queue_details_.end()) | 171 if (find_it == queue_details_.end()) |
170 return false; | 172 return false; |
171 return find_it->second.throttling_ref_count > 0; | 173 return find_it->second.throttling_ref_count > 0; |
172 } | 174 } |
173 | 175 |
174 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { | 176 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { |
175 auto find_it = queue_details_.find(task_queue); | 177 auto find_it = queue_details_.find(task_queue); |
176 if (find_it == queue_details_.end()) | 178 if (find_it == queue_details_.end()) |
177 return; | 179 return; |
178 | 180 |
179 LazyNow lazy_now(tick_clock_); | |
180 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; | 181 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; |
181 for (BudgetPool* budget_pool : budget_pools) { | 182 for (BudgetPool* budget_pool : budget_pools) { |
182 budget_pool->RemoveQueue(lazy_now.Now(), task_queue); | 183 budget_pool->UnregisterQueue(task_queue); |
183 } | 184 } |
184 | 185 |
185 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't | 186 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't |
186 // use it here. | 187 // use it here. |
187 queue_details_.erase(task_queue); | 188 queue_details_.erase(task_queue); |
188 | 189 |
189 // NOTE: Observer is automatically unregistered when unregistering task queue. | 190 // NOTE: Observer is automatically unregistered when unregistering task queue. |
190 } | 191 } |
191 | 192 |
192 void TaskQueueThrottler::OnQueueNextWakeUpChanged( | 193 void TaskQueueThrottler::OnQueueNextWakeUpChanged( |
193 TaskQueue* queue, | 194 TaskQueue* queue, |
194 base::TimeTicks next_wake_up) { | 195 base::TimeTicks next_wake_up) { |
195 if (!control_task_queue_->RunsTasksOnCurrentThread()) { | 196 if (!control_task_queue_->RunsTasksOnCurrentThread()) { |
196 control_task_queue_->PostTask( | 197 control_task_queue_->PostTask( |
197 FROM_HERE, | 198 FROM_HERE, |
198 base::Bind(forward_immediate_work_callback_, queue, next_wake_up)); | 199 base::Bind(forward_immediate_work_callback_, queue, next_wake_up)); |
199 return; | 200 return; |
200 } | 201 } |
201 | 202 |
202 TRACE_EVENT0("renderer.scheduler", | 203 TRACE_EVENT0("renderer.scheduler", |
203 "TaskQueueThrottler::OnQueueNextWakeUpChanged"); | 204 "TaskQueueThrottler::OnQueueNextWakeUpChanged"); |
204 | 205 |
205 // We don't expect this to get called for disabled queues, but we can't DCHECK | 206 // We don't expect this to get called for disabled queues, but we can't DCHECK |
206 // because of the above thread hop. Just bail out if the queue is disabled. | 207 // because of the above thread hop. Just bail out if the queue is disabled. |
207 if (!queue->IsQueueEnabled()) | 208 if (!queue->IsQueueEnabled()) |
208 return; | 209 return; |
209 | 210 |
210 base::TimeTicks now = tick_clock_->NowTicks(); | 211 base::TimeTicks now = tick_clock_->NowTicks(); |
212 | |
213 auto find_it = queue_details_.find(queue); | |
214 if (find_it == queue_details_.end()) | |
215 return; | |
216 | |
217 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
218 budget_pool->OnQueueNextWakeUpChanged(queue, now, next_wake_up); | |
219 } | |
220 | |
221 // TODO(altimin): This probably can be removed —- budget pools should | |
222 // schedule this. | |
223 base::TimeTicks next_allowed_run_time = | |
224 GetNextAllowedRunTime(queue, next_wake_up); | |
211 MaybeSchedulePumpThrottledTasks( | 225 MaybeSchedulePumpThrottledTasks( |
212 FROM_HERE, now, | 226 FROM_HERE, now, std::max(next_wake_up, next_allowed_run_time)); |
213 std::max(GetNextAllowedRunTime(now, queue), next_wake_up)); | |
214 } | 227 } |
215 | 228 |
216 void TaskQueueThrottler::PumpThrottledTasks() { | 229 void TaskQueueThrottler::PumpThrottledTasks() { |
217 TRACE_EVENT0("renderer.scheduler", "TaskQueueThrottler::PumpThrottledTasks"); | 230 TRACE_EVENT0("renderer.scheduler", "TaskQueueThrottler::PumpThrottledTasks"); |
218 pending_pump_throttled_tasks_runtime_.reset(); | 231 pending_pump_throttled_tasks_runtime_.reset(); |
219 | 232 |
220 LazyNow lazy_now(tick_clock_); | 233 LazyNow lazy_now(tick_clock_); |
221 base::Optional<base::TimeTicks> next_scheduled_delayed_task; | 234 base::Optional<base::TimeTicks> next_scheduled_delayed_task; |
222 | 235 |
236 for (const auto& pair : budget_pools_) | |
237 pair.first->OnWakeUp(lazy_now.Now()); | |
238 | |
223 for (const TaskQueueMap::value_type& map_entry : queue_details_) { | 239 for (const TaskQueueMap::value_type& map_entry : queue_details_) { |
224 TaskQueue* task_queue = map_entry.first; | 240 TaskQueue* task_queue = map_entry.first; |
225 if (task_queue->IsEmpty() || !IsThrottled(task_queue)) | 241 UpdateQueueThrottlingStateInternal(lazy_now.Now(), task_queue, true); |
226 continue; | |
227 | |
228 // Don't enable queues whose budget pool doesn't allow them to run now. | |
229 base::TimeTicks next_allowed_run_time = | |
230 GetNextAllowedRunTime(lazy_now.Now(), task_queue); | |
231 base::Optional<base::TimeTicks> next_desired_run_time = | |
232 NextTaskRunTime(&lazy_now, task_queue); | |
233 | |
234 if (next_desired_run_time && | |
235 next_allowed_run_time > next_desired_run_time.value()) { | |
236 TRACE_EVENT1( | |
237 "renderer.scheduler", | |
238 "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled", | |
239 "throttle_time_in_seconds", | |
240 (next_allowed_run_time - next_desired_run_time.value()).InSecondsF()); | |
241 | |
242 // Schedule a pump for queue which was disabled because of time budget. | |
243 next_scheduled_delayed_task = | |
244 Min(next_scheduled_delayed_task, next_allowed_run_time); | |
245 | |
246 continue; | |
247 } | |
248 | |
249 next_scheduled_delayed_task = | |
250 Min(next_scheduled_delayed_task, task_queue->GetNextScheduledWakeUp()); | |
251 | |
252 if (next_allowed_run_time > lazy_now.Now()) | |
253 continue; | |
254 | |
255 // Remove previous fence and install a new one, allowing all tasks posted | |
256 // on |task_queue| up until this point to run and block all further tasks. | |
257 task_queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
258 } | |
259 | |
260 // Maybe schedule a call to TaskQueueThrottler::PumpThrottledTasks if there is | |
261 // a pending delayed task or a throttled task ready to run. | |
262 // NOTE: posting a non-delayed task in the future will result in | |
263 // TaskQueueThrottler::OnTimeDomainHasImmediateWork being called. | |
264 if (next_scheduled_delayed_task) { | |
265 MaybeSchedulePumpThrottledTasks(FROM_HERE, lazy_now.Now(), | |
266 *next_scheduled_delayed_task); | |
267 } | 242 } |
268 } | 243 } |
269 | 244 |
270 /* static */ | 245 /* static */ |
271 base::TimeTicks TaskQueueThrottler::AlignedThrottledRunTime( | 246 base::TimeTicks TaskQueueThrottler::AlignedThrottledRunTime( |
272 base::TimeTicks unthrottled_runtime) { | 247 base::TimeTicks unthrottled_runtime) { |
273 const base::TimeDelta one_second = base::TimeDelta::FromSeconds(1); | 248 const base::TimeDelta one_second = base::TimeDelta::FromSeconds(1); |
274 return unthrottled_runtime + one_second - | 249 return unthrottled_runtime + one_second - |
275 ((unthrottled_runtime - base::TimeTicks()) % one_second); | 250 ((unthrottled_runtime - base::TimeTicks()) % one_second); |
276 } | 251 } |
(...skipping 29 matching lines...) Expand all Loading... | |
306 } | 281 } |
307 | 282 |
308 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool( | 283 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool( |
309 const char* name) { | 284 const char* name) { |
310 CPUTimeBudgetPool* time_budget_pool = | 285 CPUTimeBudgetPool* time_budget_pool = |
311 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks()); | 286 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks()); |
312 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); | 287 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); |
313 return time_budget_pool; | 288 return time_budget_pool; |
314 } | 289 } |
315 | 290 |
291 WakeUpBudgetPool* TaskQueueThrottler::CreateWakeUpBudgetPool(const char* name) { | |
292 WakeUpBudgetPool* wake_up_budget_pool = | |
293 new WakeUpBudgetPool(name, this, tick_clock_->NowTicks()); | |
294 budget_pools_[wake_up_budget_pool] = base::WrapUnique(wake_up_budget_pool); | |
295 return wake_up_budget_pool; | |
296 } | |
297 | |
316 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, | 298 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, |
317 base::TimeTicks start_time, | 299 base::TimeTicks start_time, |
318 base::TimeTicks end_time) { | 300 base::TimeTicks end_time) { |
319 if (!IsThrottled(task_queue)) | 301 if (!IsThrottled(task_queue)) |
320 return; | 302 return; |
321 | 303 |
322 auto find_it = queue_details_.find(task_queue); | 304 auto find_it = queue_details_.find(task_queue); |
323 if (find_it == queue_details_.end()) | 305 if (find_it == queue_details_.end()) |
324 return; | 306 return; |
325 | 307 |
326 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | 308 for (BudgetPool* budget_pool : find_it->second.budget_pools) { |
327 budget_pool->RecordTaskRunTime(start_time, end_time); | 309 budget_pool->RecordTaskRunTime(task_queue, start_time, end_time); |
328 if (!budget_pool->HasEnoughBudgetToRun(end_time)) | |
329 budget_pool->BlockThrottledQueues(end_time); | |
330 } | 310 } |
331 } | 311 } |
332 | 312 |
333 void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) { | 313 void TaskQueueThrottler::UpdateQueueThrottlingState(base::TimeTicks now, |
334 if (!IsThrottled(queue)) | 314 TaskQueue* queue) { |
315 UpdateQueueThrottlingStateInternal(now, queue, false); | |
316 } | |
317 | |
318 void TaskQueueThrottler::UpdateQueueThrottlingStateInternal(base::TimeTicks now, | |
319 TaskQueue* queue, | |
320 bool is_wake_up) { | |
321 if (!queue->IsQueueEnabled() || !IsThrottled(queue)) { | |
335 return; | 322 return; |
323 } | |
336 | 324 |
337 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | 325 LazyNow lazy_now(now); |
338 SchedulePumpQueue(FROM_HERE, now, queue); | 326 |
327 base::Optional<base::TimeTicks> next_desired_run_time = | |
328 NextTaskRunTime(&lazy_now, queue); | |
329 | |
330 if (!next_desired_run_time) { | |
331 // This queue is empty. Given that new task can arrive at any moment, | |
332 // block the queue completely and update the state upon the notification | |
333 // about a new task. | |
334 queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
335 return; | |
336 } | |
337 | |
338 if (CanRunTasksAt(queue, now, false) && | |
339 CanRunTasksAt(queue, next_desired_run_time.value(), false)) { | |
340 // We can run up until the next task uninterrupted. Remove the fence | |
Sami
2017/05/03 16:53:05
Wondering about the wording here ("uninterrupted")
altimin
2017/05/04 10:50:06
Made the comment more explicit.
| |
341 // to allow new tasks to run immediately. | |
342 queue->RemoveFence(); | |
343 | |
344 // TaskQueueThrottler does not schedule wake-ups implicitly, we need | |
345 // to be explicit. | |
346 if (next_desired_run_time.value() != now) { | |
347 time_domain_->SetNextTaskRunTime(next_desired_run_time.value()); | |
348 } | |
349 return; | |
350 } | |
351 | |
352 if (CanRunTasksAt(queue, now, is_wake_up)) { | |
353 // We can run task now, but we can't run until the next scheduled task. | |
354 // Insert a fresh fence to unblock queue and schedule a pump for the | |
355 // next wake-up. | |
356 queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
357 | |
358 base::Optional<base::TimeTicks> next_wake_up = | |
359 queue->GetNextScheduledWakeUp(); | |
360 if (next_wake_up) { | |
361 MaybeSchedulePumpThrottledTasks( | |
362 FROM_HERE, now, GetNextAllowedRunTime(queue, next_wake_up.value())); | |
363 } | |
364 return; | |
365 } | |
366 | |
367 base::TimeTicks next_run_time = | |
368 GetNextAllowedRunTime(queue, next_desired_run_time.value()); | |
369 | |
370 // Insert a fence of an approriate type. | |
371 base::Optional<QueueBlockType> block_type = GetQueueBlockType(now, queue); | |
372 DCHECK(block_type); | |
373 | |
374 switch (block_type.value()) { | |
375 case QueueBlockType::kAllTasks: | |
376 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | |
377 | |
378 { | |
379 // Braces limit the scope for a declared variable. Does not compile | |
380 // otherwise. | |
381 TRACE_EVENT1( | |
382 "renderer.scheduler", | |
383 "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled", | |
384 "throttle_time_in_seconds", | |
385 (next_run_time - next_desired_run_time.value()).InSecondsF()); | |
386 } | |
387 break; | |
388 case QueueBlockType::kNewTasksOnly: | |
389 if (!queue->HasFence()) { | |
390 // Insert a new non-fully blocking fence only when there is no fence | |
391 // already in order avoid undesired unblocking of old tasks. | |
392 queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
393 } | |
394 break; | |
395 } | |
396 | |
397 // Schedule a pump. | |
398 MaybeSchedulePumpThrottledTasks(FROM_HERE, now, next_run_time); | |
399 } | |
400 | |
401 base::Optional<QueueBlockType> TaskQueueThrottler::GetQueueBlockType( | |
402 base::TimeTicks now, | |
403 TaskQueue* queue) { | |
404 auto find_it = queue_details_.find(queue); | |
405 if (find_it == queue_details_.end()) | |
406 return base::nullopt; | |
407 | |
408 bool has_new_tasks_only_block = false; | |
409 | |
410 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
411 if (!budget_pool->CanRunTasksAt(now, false)) { | |
412 if (budget_pool->GetBlockType() == QueueBlockType::kAllTasks) | |
413 return QueueBlockType::kAllTasks; | |
414 DCHECK_EQ(budget_pool->GetBlockType(), QueueBlockType::kNewTasksOnly); | |
415 has_new_tasks_only_block = true; | |
416 } | |
417 } | |
418 | |
419 if (has_new_tasks_only_block) | |
420 return QueueBlockType::kNewTasksOnly; | |
421 return base::nullopt; | |
339 } | 422 } |
340 | 423 |
341 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state, | 424 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state, |
342 base::TimeTicks now) const { | 425 base::TimeTicks now) const { |
343 if (pending_pump_throttled_tasks_runtime_) { | 426 if (pending_pump_throttled_tasks_runtime_) { |
344 state->SetDouble( | 427 state->SetDouble( |
345 "next_throttled_tasks_pump_in_seconds", | 428 "next_throttled_tasks_pump_in_seconds", |
346 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF()); | 429 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF()); |
347 } | 430 } |
348 | 431 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 | 472 |
390 find_it->second.budget_pools.erase(budget_pool); | 473 find_it->second.budget_pools.erase(budget_pool); |
391 | 474 |
392 MaybeDeleteQueueMetadata(find_it); | 475 MaybeDeleteQueueMetadata(find_it); |
393 } | 476 } |
394 | 477 |
395 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) { | 478 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) { |
396 budget_pools_.erase(budget_pool); | 479 budget_pools_.erase(budget_pool); |
397 } | 480 } |
398 | 481 |
399 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) { | 482 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime( |
400 SchedulePumpQueue(FROM_HERE, now, queue); | 483 TaskQueue* queue, |
401 } | 484 base::TimeTicks desired_run_time) { |
402 | 485 base::TimeTicks next_run_time = desired_run_time; |
403 void TaskQueueThrottler::SchedulePumpQueue( | |
404 const tracked_objects::Location& from_here, | |
405 base::TimeTicks now, | |
406 TaskQueue* queue) { | |
407 if (!IsThrottled(queue)) | |
408 return; | |
409 | |
410 LazyNow lazy_now(now); | |
411 base::Optional<base::TimeTicks> next_desired_run_time = | |
412 NextTaskRunTime(&lazy_now, queue); | |
413 if (!next_desired_run_time) | |
414 return; | |
415 | |
416 base::Optional<base::TimeTicks> next_run_time = | |
417 Max(next_desired_run_time, GetNextAllowedRunTime(now, queue)); | |
418 | |
419 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value()); | |
420 } | |
421 | |
422 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now, | |
423 TaskQueue* queue) { | |
424 base::TimeTicks next_run_time = now; | |
425 | 486 |
426 auto find_it = queue_details_.find(queue); | 487 auto find_it = queue_details_.find(queue); |
427 if (find_it == queue_details_.end()) | 488 if (find_it == queue_details_.end()) |
428 return next_run_time; | 489 return next_run_time; |
429 | 490 |
430 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | 491 for (BudgetPool* budget_pool : find_it->second.budget_pools) { |
431 next_run_time = | 492 next_run_time = std::max( |
432 std::max(next_run_time, budget_pool->GetNextAllowedRunTime()); | 493 next_run_time, budget_pool->GetNextAllowedRunTime(desired_run_time)); |
433 } | 494 } |
434 | 495 |
435 return next_run_time; | 496 return next_run_time; |
436 } | 497 } |
437 | 498 |
499 bool TaskQueueThrottler::CanRunTasksAt(TaskQueue* queue, | |
500 base::TimeTicks moment, | |
501 bool is_wake_up) { | |
502 auto find_it = queue_details_.find(queue); | |
503 if (find_it == queue_details_.end()) | |
504 return true; | |
505 | |
506 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
507 if (!budget_pool->CanRunTasksAt(moment, is_wake_up)) | |
508 return false; | |
509 } | |
510 | |
511 return true; | |
512 } | |
513 | |
438 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { | 514 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { |
439 if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty()) | 515 if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty()) |
440 queue_details_.erase(it); | 516 queue_details_.erase(it); |
441 } | 517 } |
442 | 518 |
443 void TaskQueueThrottler::DisableThrottling() { | 519 void TaskQueueThrottler::DisableThrottling() { |
444 if (!allow_throttling_) | 520 if (!allow_throttling_) |
445 return; | 521 return; |
446 | 522 |
447 allow_throttling_ = false; | 523 allow_throttling_ = false; |
(...skipping 26 matching lines...) Expand all Loading... | |
474 for (const auto& map_entry : queue_details_) { | 550 for (const auto& map_entry : queue_details_) { |
475 if (map_entry.second.throttling_ref_count == 0) | 551 if (map_entry.second.throttling_ref_count == 0) |
476 continue; | 552 continue; |
477 | 553 |
478 TaskQueue* queue = map_entry.first; | 554 TaskQueue* queue = map_entry.first; |
479 | 555 |
480 // Throttling is enabled and task queue should be blocked immediately | 556 // Throttling is enabled and task queue should be blocked immediately |
481 // to enforce task alignment. | 557 // to enforce task alignment. |
482 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | 558 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); |
483 queue->SetTimeDomain(time_domain_.get()); | 559 queue->SetTimeDomain(time_domain_.get()); |
484 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue); | 560 UpdateQueueThrottlingState(lazy_now.Now(), queue); |
485 } | 561 } |
486 | 562 |
487 TRACE_EVENT0("renderer.scheduler", "TaskQueueThrottler_EnableThrottling"); | 563 TRACE_EVENT0("renderer.scheduler", "TaskQueueThrottler_EnableThrottling"); |
488 } | 564 } |
489 | 565 |
490 } // namespace scheduler | 566 } // namespace scheduler |
491 } // namespace blink | 567 } // namespace blink |
OLD | NEW |