Chromium Code Reviews| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 if (!task_queue->IsEmpty()) { | 137 if (!task_queue->IsEmpty()) { |
| 138 LazyNow lazy_now(tick_clock_); | 138 LazyNow lazy_now(tick_clock_); |
| 139 OnQueueNextWakeUpChanged(task_queue, | 139 OnQueueNextWakeUpChanged(task_queue, |
| 140 NextTaskRunTime(&lazy_now, task_queue).value()); | 140 NextTaskRunTime(&lazy_now, task_queue).value()); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { | 144 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { |
| 145 TaskQueueMap::iterator iter = queue_details_.find(task_queue); | 145 TaskQueueMap::iterator iter = queue_details_.find(task_queue); |
| 146 | 146 |
| 147 if (iter == queue_details_.end() || | 147 if (iter == queue_details_.end()) |
| 148 --iter->second.throttling_ref_count != 0) { | |
| 149 return; | 148 return; |
| 150 } | 149 if (iter->second.throttling_ref_count == 0) |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
That looks really weird. Is this papering over a
altimin
2017/04/25 13:22:35
There is a special test ensuring that extra Decrea
| |
| 150 return; | |
| 151 if (--iter->second.throttling_ref_count != 0) | |
| 152 return; | |
| 151 | 153 |
| 152 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUnthrottled", | 154 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUnthrottled", |
| 153 "task_queue", task_queue); | 155 "task_queue", task_queue); |
| 154 | 156 |
| 155 task_queue->SetObserver(nullptr); | 157 task_queue->SetObserver(nullptr); |
| 156 | 158 |
| 157 MaybeDeleteQueueMetadata(iter); | 159 MaybeDeleteQueueMetadata(iter); |
| 158 | 160 |
| 159 if (!allow_throttling_) | 161 if (!allow_throttling_) |
| 160 return; | 162 return; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 171 if (find_it == queue_details_.end()) | 173 if (find_it == queue_details_.end()) |
| 172 return false; | 174 return false; |
| 173 return find_it->second.throttling_ref_count > 0; | 175 return find_it->second.throttling_ref_count > 0; |
| 174 } | 176 } |
| 175 | 177 |
| 176 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { | 178 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { |
| 177 auto find_it = queue_details_.find(task_queue); | 179 auto find_it = queue_details_.find(task_queue); |
| 178 if (find_it == queue_details_.end()) | 180 if (find_it == queue_details_.end()) |
| 179 return; | 181 return; |
| 180 | 182 |
| 181 LazyNow lazy_now(tick_clock_); | |
| 182 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; | 183 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; |
| 183 for (BudgetPool* budget_pool : budget_pools) { | 184 for (BudgetPool* budget_pool : budget_pools) { |
| 184 budget_pool->RemoveQueue(lazy_now.Now(), task_queue); | 185 budget_pool->UnregisterQueue(task_queue); |
| 185 } | 186 } |
| 186 | 187 |
| 187 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't | 188 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't |
| 188 // use it here. | 189 // use it here. |
| 189 queue_details_.erase(task_queue); | 190 queue_details_.erase(task_queue); |
| 190 | 191 |
| 191 // NOTE: Observer is automatically unregistered when unregistering task queue. | 192 // NOTE: Observer is automatically unregistered when unregistering task queue. |
| 192 } | 193 } |
| 193 | 194 |
| 194 void TaskQueueThrottler::OnQueueNextWakeUpChanged( | 195 void TaskQueueThrottler::OnQueueNextWakeUpChanged( |
| 195 TaskQueue* queue, | 196 TaskQueue* queue, |
| 196 base::TimeTicks next_wake_up) { | 197 base::TimeTicks next_wake_up) { |
| 197 if (!task_runner_->RunsTasksOnCurrentThread()) { | 198 if (!task_runner_->RunsTasksOnCurrentThread()) { |
| 198 task_runner_->PostTask( | 199 task_runner_->PostTask( |
| 199 FROM_HERE, | 200 FROM_HERE, |
| 200 base::Bind(forward_immediate_work_callback_, queue, next_wake_up)); | 201 base::Bind(forward_immediate_work_callback_, queue, next_wake_up)); |
| 201 return; | 202 return; |
| 202 } | 203 } |
| 203 | 204 |
| 204 TRACE_EVENT0(tracing_category_, | 205 TRACE_EVENT0(tracing_category_, |
| 205 "TaskQueueThrottler::OnQueueNextWakeUpChanged"); | 206 "TaskQueueThrottler::OnQueueNextWakeUpChanged"); |
| 206 | 207 |
| 207 // We don't expect this to get called for disabled queues, but we can't DCHECK | 208 // We don't expect this to get called for disabled queues, but we can't DCHECK |
| 208 // because of the above thread hop. Just bail out if the queue is disabled. | 209 // because of the above thread hop. Just bail out if the queue is disabled. |
| 209 if (!queue->IsQueueEnabled()) | 210 if (!queue->IsQueueEnabled()) |
| 210 return; | 211 return; |
| 211 | 212 |
| 212 base::TimeTicks now = tick_clock_->NowTicks(); | 213 base::TimeTicks now = tick_clock_->NowTicks(); |
| 214 | |
| 215 auto find_it = queue_details_.find(queue); | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
I don't remember off hand if return value optimiza
altimin
2017/04/25 13:22:35
auto find_it is a common pattern here. I don't wan
| |
| 216 if (find_it == queue_details_.end()) | |
| 217 return; | |
| 218 | |
| 219 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
| 220 budget_pool->OnTaskQueueHasWork(queue, now, next_wake_up); | |
| 221 } | |
| 222 | |
| 223 base::TimeTicks next_allowed_run_time = | |
| 224 GetNextAllowedRunTime(queue, now, next_wake_up); | |
| 225 // TODO(altimin): Remove after moving to budget pools completely. | |
| 213 MaybeSchedulePumpThrottledTasks( | 226 MaybeSchedulePumpThrottledTasks( |
| 214 FROM_HERE, now, | 227 FROM_HERE, now, std::max(next_wake_up, next_allowed_run_time)); |
| 215 std::max(GetNextAllowedRunTime(now, queue), next_wake_up)); | |
| 216 } | 228 } |
| 217 | 229 |
| 218 void TaskQueueThrottler::PumpThrottledTasks() { | 230 void TaskQueueThrottler::PumpThrottledTasks() { |
| 219 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks"); | 231 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks"); |
| 220 pending_pump_throttled_tasks_runtime_.reset(); | 232 pending_pump_throttled_tasks_runtime_.reset(); |
| 221 | 233 |
| 222 LazyNow lazy_now(tick_clock_); | 234 LazyNow lazy_now(tick_clock_); |
| 223 base::Optional<base::TimeTicks> next_scheduled_delayed_task; | 235 base::Optional<base::TimeTicks> next_scheduled_delayed_task; |
| 224 | 236 |
| 237 for (const auto& it : budget_pools_) | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
uber nit: s/it/pair ;)
altimin
2017/04/25 13:22:35
Done.
| |
| 238 it.first->OnWakeup(lazy_now.Now()); | |
| 239 | |
| 225 for (const TaskQueueMap::value_type& map_entry : queue_details_) { | 240 for (const TaskQueueMap::value_type& map_entry : queue_details_) { |
| 226 TaskQueue* task_queue = map_entry.first; | 241 TaskQueue* task_queue = map_entry.first; |
| 227 if (task_queue->IsEmpty() || !IsThrottled(task_queue)) | 242 if (task_queue->IsEmpty() || !task_queue->IsQueueEnabled() || |
| 243 !IsThrottled(task_queue)) { | |
| 228 continue; | 244 continue; |
| 245 } | |
| 229 | 246 |
| 230 // Don't enable queues whose budget pool doesn't allow them to run now. | |
| 231 base::TimeTicks next_allowed_run_time = | |
| 232 GetNextAllowedRunTime(lazy_now.Now(), task_queue); | |
| 233 base::Optional<base::TimeTicks> next_desired_run_time = | 247 base::Optional<base::TimeTicks> next_desired_run_time = |
| 234 NextTaskRunTime(&lazy_now, task_queue); | 248 NextTaskRunTime(&lazy_now, task_queue); |
| 235 | 249 |
| 236 if (next_desired_run_time && | 250 if (!next_desired_run_time) { |
| 237 next_allowed_run_time > next_desired_run_time.value()) { | 251 // This task queue does not any tasks. |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
Looks like you're missing a word in the comment.
altimin
2017/04/25 13:22:35
Done.
| |
| 252 task_queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
Is it possible to get here? The queue has to be e
altimin
2017/04/25 13:22:35
Done.
| |
| 253 continue; | |
| 254 } | |
| 255 | |
| 256 base::TimeTicks next_run_time = GetNextAllowedRunTime( | |
| 257 task_queue, lazy_now.Now(), next_desired_run_time.value()); | |
| 258 | |
| 259 if (next_run_time > lazy_now.Now()) { | |
| 238 TRACE_EVENT1( | 260 TRACE_EVENT1( |
| 239 tracing_category_, | 261 tracing_category_, |
| 240 "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled", | 262 "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled", |
| 241 "throttle_time_in_seconds", | 263 "throttle_time_in_seconds", |
| 242 (next_allowed_run_time - next_desired_run_time.value()).InSecondsF()); | 264 (next_run_time - next_desired_run_time.value()).InSecondsF()); |
| 243 | 265 |
| 244 // Schedule a pump for queue which was disabled because of time budget. | |
| 245 next_scheduled_delayed_task = | 266 next_scheduled_delayed_task = |
| 246 Min(next_scheduled_delayed_task, next_allowed_run_time); | 267 Min(next_scheduled_delayed_task, next_run_time); |
| 247 | 268 |
| 248 continue; | 269 continue; |
| 249 } | 270 } |
| 250 | 271 |
| 251 next_scheduled_delayed_task = | 272 base::Optional<base::TimeTicks> next_wake_up = |
| 252 Min(next_scheduled_delayed_task, task_queue->GetNextScheduledWakeUp()); | 273 task_queue->GetNextScheduledWakeUp(); |
| 253 | 274 |
| 254 if (next_allowed_run_time > lazy_now.Now()) | 275 if (next_wake_up) { |
| 276 next_scheduled_delayed_task = | |
| 277 Min(next_scheduled_delayed_task, | |
| 278 GetNextAllowedRunTime(task_queue, lazy_now.Now(), | |
| 279 next_wake_up.value())); | |
| 280 } | |
| 281 | |
| 282 if (CanRunTasksUntil(task_queue, lazy_now.Now(), | |
| 283 next_desired_run_time.value())) { | |
| 284 // Remove fence if we can new tasks until next wakeup. | |
| 285 task_queue->RemoveFence(); | |
| 255 continue; | 286 continue; |
| 287 } | |
| 256 | 288 |
| 257 // Remove previous fence and install a new one, allowing all tasks posted | 289 // Remove previous fence and install a new one, allowing all tasks posted |
| 258 // on |task_queue| up until this point to run and block all further tasks. | 290 // on |task_queue| up until this point to run and block all further tasks. |
| 259 task_queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | 291 task_queue->InsertFence(TaskQueue::InsertFencePosition::NOW); |
| 260 } | 292 } |
| 261 | 293 |
| 262 // Maybe schedule a call to TaskQueueThrottler::PumpThrottledTasks if there is | 294 // Maybe schedule a call to TaskQueueThrottler::PumpThrottledTasks if there is |
| 263 // a pending delayed task or a throttled task ready to run. | 295 // a pending delayed task or a throttled task ready to run. |
| 264 // NOTE: posting a non-delayed task in the future will result in | 296 // NOTE: posting a non-delayed task in the future will result in |
| 265 // TaskQueueThrottler::OnTimeDomainHasImmediateWork being called. | 297 // TaskQueueThrottler::OnTimeDomainHasImmediateWork being called. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 } | 340 } |
| 309 | 341 |
| 310 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool( | 342 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool( |
| 311 const char* name) { | 343 const char* name) { |
| 312 CPUTimeBudgetPool* time_budget_pool = | 344 CPUTimeBudgetPool* time_budget_pool = |
| 313 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks()); | 345 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks()); |
| 314 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); | 346 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); |
| 315 return time_budget_pool; | 347 return time_budget_pool; |
| 316 } | 348 } |
| 317 | 349 |
| 350 WakeupBudgetPool* TaskQueueThrottler::CreateWakeupBudgetPool(const char* name) { | |
| 351 WakeupBudgetPool* wakeup_budget_pool = | |
| 352 new WakeupBudgetPool(name, this, tick_clock_->NowTicks()); | |
| 353 budget_pools_[wakeup_budget_pool] = base::WrapUnique(wakeup_budget_pool); | |
| 354 return wakeup_budget_pool; | |
| 355 } | |
| 356 | |
| 318 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, | 357 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, |
| 319 base::TimeTicks start_time, | 358 base::TimeTicks start_time, |
| 320 base::TimeTicks end_time) { | 359 base::TimeTicks end_time) { |
| 321 if (!IsThrottled(task_queue)) | 360 if (!IsThrottled(task_queue)) |
| 322 return; | 361 return; |
| 323 | 362 |
| 324 auto find_it = queue_details_.find(task_queue); | 363 auto find_it = queue_details_.find(task_queue); |
| 325 if (find_it == queue_details_.end()) | 364 if (find_it == queue_details_.end()) |
| 326 return; | 365 return; |
| 327 | 366 |
| 328 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | 367 for (BudgetPool* budget_pool : find_it->second.budget_pools) { |
| 329 budget_pool->RecordTaskRunTime(start_time, end_time); | 368 budget_pool->RecordTaskRunTime(task_queue, start_time, end_time); |
| 330 if (!budget_pool->HasEnoughBudgetToRun(end_time)) | 369 if (!budget_pool->CanRunTasksAt(end_time)) |
| 331 budget_pool->BlockThrottledQueues(end_time); | 370 budget_pool->BlockThrottledQueues(end_time); |
| 332 } | 371 } |
| 333 } | 372 } |
| 334 | 373 |
| 335 void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) { | 374 void TaskQueueThrottler::BlockQueue(QueueBlockType block_type, |
| 375 base::TimeTicks now, | |
| 376 TaskQueue* queue) { | |
| 336 if (!IsThrottled(queue)) | 377 if (!IsThrottled(queue)) |
| 337 return; | 378 return; |
| 338 | 379 |
| 339 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | 380 if (block_type == QueueBlockType::FULL) { |
| 381 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | |
| 382 } else { // block_type == BlockType::NEW_TASKS_ONLY | |
| 383 if (!queue->HasFence()) { | |
| 384 queue->InsertFence(TaskQueue::InsertFencePosition::NOW); | |
| 385 } | |
| 386 } | |
| 340 SchedulePumpQueue(FROM_HERE, now, queue); | 387 SchedulePumpQueue(FROM_HERE, now, queue); |
| 341 } | 388 } |
| 342 | 389 |
| 343 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state, | 390 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state, |
| 344 base::TimeTicks now) const { | 391 base::TimeTicks now) const { |
| 345 if (pending_pump_throttled_tasks_runtime_) { | 392 if (pending_pump_throttled_tasks_runtime_) { |
| 346 state->SetDouble( | 393 state->SetDouble( |
| 347 "next_throttled_tasks_pump_in_seconds", | 394 "next_throttled_tasks_pump_in_seconds", |
| 348 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF()); | 395 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF()); |
| 349 } | 396 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 find_it->second.budget_pools.erase(budget_pool); | 439 find_it->second.budget_pools.erase(budget_pool); |
| 393 | 440 |
| 394 MaybeDeleteQueueMetadata(find_it); | 441 MaybeDeleteQueueMetadata(find_it); |
| 395 } | 442 } |
| 396 | 443 |
| 397 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) { | 444 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) { |
| 398 budget_pools_.erase(budget_pool); | 445 budget_pools_.erase(budget_pool); |
| 399 } | 446 } |
| 400 | 447 |
| 401 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) { | 448 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) { |
| 402 SchedulePumpQueue(FROM_HERE, now, queue); | 449 if (queue->HasFence()) |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
I hope we don't get tempted to use fences for some
altimin
2017/04/25 13:22:36
Actually, we don't need this condition here.
| |
| 450 SchedulePumpQueue(FROM_HERE, now, queue); | |
| 403 } | 451 } |
| 404 | 452 |
| 405 void TaskQueueThrottler::SchedulePumpQueue( | 453 void TaskQueueThrottler::SchedulePumpQueue( |
| 406 const tracked_objects::Location& from_here, | 454 const tracked_objects::Location& from_here, |
| 407 base::TimeTicks now, | 455 base::TimeTicks now, |
| 408 TaskQueue* queue) { | 456 TaskQueue* queue) { |
| 409 if (!IsThrottled(queue)) | 457 if (!IsThrottled(queue) || !queue->IsQueueEnabled()) |
| 410 return; | 458 return; |
| 411 | 459 |
| 412 LazyNow lazy_now(now); | 460 LazyNow lazy_now(now); |
| 413 base::Optional<base::TimeTicks> next_desired_run_time = | 461 base::Optional<base::TimeTicks> next_desired_run_time = |
| 414 NextTaskRunTime(&lazy_now, queue); | 462 NextTaskRunTime(&lazy_now, queue); |
| 415 if (!next_desired_run_time) | 463 if (!next_desired_run_time) { |
| 416 return; | 464 return; |
| 417 | 465 } |
| 418 base::Optional<base::TimeTicks> next_run_time = | 466 base::Optional<base::TimeTicks> next_run_time; |
| 419 Max(next_desired_run_time, GetNextAllowedRunTime(now, queue)); | 467 if (next_desired_run_time) { |
| 468 next_run_time = | |
| 469 GetNextAllowedRunTime(queue, now, next_desired_run_time.value()); | |
| 470 } | |
| 420 | 471 |
| 421 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value()); | 472 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value()); |
| 422 } | 473 } |
| 423 | 474 |
| 424 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now, | 475 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime( |
| 425 TaskQueue* queue) { | 476 TaskQueue* queue, |
| 477 base::TimeTicks now, | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
I'm not 100% on this, but I wonder if things would
altimin
2017/04/25 13:22:35
Agreed.
| |
| 478 base::TimeTicks desired_run_time) { | |
| 426 base::TimeTicks next_run_time = now; | 479 base::TimeTicks next_run_time = now; |
| 427 | 480 |
| 428 auto find_it = queue_details_.find(queue); | 481 auto find_it = queue_details_.find(queue); |
| 429 if (find_it == queue_details_.end()) | 482 if (find_it == queue_details_.end()) |
| 430 return next_run_time; | 483 return next_run_time; |
| 431 | 484 |
| 432 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | 485 for (BudgetPool* budget_pool : find_it->second.budget_pools) { |
| 433 next_run_time = | 486 next_run_time = std::max( |
| 434 std::max(next_run_time, budget_pool->GetNextAllowedRunTime()); | 487 next_run_time, budget_pool->GetNextAllowedRunTime(desired_run_time)); |
| 435 } | 488 } |
| 436 | 489 |
| 437 return next_run_time; | 490 return next_run_time; |
| 438 } | 491 } |
| 439 | 492 |
| 493 bool TaskQueueThrottler::CanRunTasksAt(TaskQueue* queue, | |
| 494 base::TimeTicks moment) { | |
| 495 auto find_it = queue_details_.find(queue); | |
| 496 if (find_it == queue_details_.end()) | |
| 497 return true; | |
| 498 | |
| 499 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
| 500 if (!budget_pool->CanRunTasksAt(moment)) | |
| 501 return false; | |
| 502 } | |
| 503 | |
| 504 return true; | |
| 505 } | |
| 506 | |
| 507 bool TaskQueueThrottler::CanRunTasksUntil(TaskQueue* queue, | |
| 508 base::TimeTicks now, | |
| 509 base::TimeTicks moment) { | |
| 510 auto find_it = queue_details_.find(queue); | |
| 511 if (find_it == queue_details_.end()) | |
| 512 return true; | |
| 513 | |
| 514 for (BudgetPool* budget_pool : find_it->second.budget_pools) { | |
| 515 if (!budget_pool->CanRunTasksUntil(now, moment)) | |
| 516 return false; | |
| 517 } | |
| 518 | |
| 519 return true; | |
| 520 } | |
| 521 | |
| 440 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { | 522 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { |
| 441 if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty()) | 523 if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty()) |
| 442 queue_details_.erase(it); | 524 queue_details_.erase(it); |
| 443 } | 525 } |
| 444 | 526 |
| 445 void TaskQueueThrottler::DisableThrottling() { | 527 void TaskQueueThrottler::DisableThrottling() { |
| 446 if (!allow_throttling_) | 528 if (!allow_throttling_) |
| 447 return; | 529 return; |
| 448 | 530 |
| 449 allow_throttling_ = false; | 531 allow_throttling_ = false; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); | 566 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); |
| 485 queue->SetTimeDomain(time_domain_.get()); | 567 queue->SetTimeDomain(time_domain_.get()); |
| 486 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue); | 568 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue); |
| 487 } | 569 } |
| 488 | 570 |
| 489 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling"); | 571 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling"); |
| 490 } | 572 } |
| 491 | 573 |
| 492 } // namespace scheduler | 574 } // namespace scheduler |
| 493 } // namespace blink | 575 } // namespace blink |
| OLD | NEW |