Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc

Issue 2754853003: [scheduler] Support adding one queue to multiple budget pools (Closed)
Patch Set: Address comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 if (!allow_throttling_) 163 if (!allow_throttling_)
164 return false; 164 return false;
165 165
166 auto find_it = queue_details_.find(task_queue); 166 auto find_it = queue_details_.find(task_queue);
167 if (find_it == queue_details_.end()) 167 if (find_it == queue_details_.end())
168 return false; 168 return false;
169 return find_it->second.throttling_ref_count > 0; 169 return find_it->second.throttling_ref_count > 0;
170 } 170 }
171 171
172 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { 172 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) {
173 LazyNow lazy_now(tick_clock_);
174 auto find_it = queue_details_.find(task_queue); 173 auto find_it = queue_details_.find(task_queue);
175
176 if (find_it == queue_details_.end()) 174 if (find_it == queue_details_.end())
177 return; 175 return;
178 176
179 if (find_it->second.budget_pool) 177 LazyNow lazy_now(tick_clock_);
180 find_it->second.budget_pool->RemoveQueue(lazy_now.Now(), task_queue); 178 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools;
179 for (BudgetPool* budget_pool : budget_pools) {
180 budget_pool->RemoveQueue(lazy_now.Now(), task_queue);
181 }
181 182
182 queue_details_.erase(find_it); 183 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't
184 // use it here.
185 queue_details_.erase(task_queue);
183 } 186 }
184 187
185 void TaskQueueThrottler::OnTimeDomainHasImmediateWork(TaskQueue* queue) { 188 void TaskQueueThrottler::OnTimeDomainHasImmediateWork(TaskQueue* queue) {
186 // Forward to the main thread if called from another thread 189 // Forward to the main thread if called from another thread
187 if (!task_runner_->RunsTasksOnCurrentThread()) { 190 if (!task_runner_->RunsTasksOnCurrentThread()) {
188 task_runner_->PostTask(FROM_HERE, 191 task_runner_->PostTask(FROM_HERE,
189 base::Bind(forward_immediate_work_callback_, queue)); 192 base::Bind(forward_immediate_work_callback_, queue));
190 return; 193 return;
191 } 194 }
192 TRACE_EVENT0(tracing_category_, 195 TRACE_EVENT0(tracing_category_,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); 321 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool);
319 return time_budget_pool; 322 return time_budget_pool;
320 } 323 }
321 324
322 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, 325 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue,
323 base::TimeTicks start_time, 326 base::TimeTicks start_time,
324 base::TimeTicks end_time) { 327 base::TimeTicks end_time) {
325 if (!IsThrottled(task_queue)) 328 if (!IsThrottled(task_queue))
326 return; 329 return;
327 330
328 BudgetPool* budget_pool = GetBudgetPoolForQueue(task_queue); 331 auto find_it = queue_details_.find(task_queue);
329 if (!budget_pool) 332 if (find_it == queue_details_.end())
330 return; 333 return;
331 334
332 budget_pool->RecordTaskRunTime(start_time, end_time); 335 for (BudgetPool* budget_pool : find_it->second.budget_pools) {
333 if (!budget_pool->HasEnoughBudgetToRun(end_time)) 336 budget_pool->RecordTaskRunTime(start_time, end_time);
334 budget_pool->BlockThrottledQueues(end_time); 337 if (!budget_pool->HasEnoughBudgetToRun(end_time))
338 budget_pool->BlockThrottledQueues(end_time);
339 }
335 } 340 }
336 341
337 void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) { 342 void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) {
338 if (!IsThrottled(queue)) 343 if (!IsThrottled(queue))
339 return; 344 return;
340 345
341 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); 346 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
342 SchedulePumpQueue(FROM_HERE, now, queue); 347 SchedulePumpQueue(FROM_HERE, now, queue);
343 } 348 }
344 349
(...skipping 26 matching lines...) Expand all
371 state->EndDictionary(); 376 state->EndDictionary();
372 } 377 }
373 378
374 void TaskQueueThrottler::AddQueueToBudgetPool(TaskQueue* queue, 379 void TaskQueueThrottler::AddQueueToBudgetPool(TaskQueue* queue,
375 BudgetPool* budget_pool) { 380 BudgetPool* budget_pool) {
376 std::pair<TaskQueueMap::iterator, bool> insert_result = 381 std::pair<TaskQueueMap::iterator, bool> insert_result =
377 queue_details_.insert(std::make_pair(queue, Metadata())); 382 queue_details_.insert(std::make_pair(queue, Metadata()));
378 383
379 Metadata& metadata = insert_result.first->second; 384 Metadata& metadata = insert_result.first->second;
380 385
381 DCHECK(!metadata.budget_pool); 386 DCHECK(metadata.budget_pools.find(budget_pool) ==
382 metadata.budget_pool = budget_pool; 387 metadata.budget_pools.end());
388
389 metadata.budget_pools.insert(budget_pool);
383 } 390 }
384 391
385 void TaskQueueThrottler::RemoveQueueFromBudgetPool(TaskQueue* queue, 392 void TaskQueueThrottler::RemoveQueueFromBudgetPool(TaskQueue* queue,
386 BudgetPool* budget_pool) { 393 BudgetPool* budget_pool) {
387 auto find_it = queue_details_.find(queue); 394 auto find_it = queue_details_.find(queue);
388 DCHECK(find_it != queue_details_.end() && 395 DCHECK(find_it != queue_details_.end() &&
389 find_it->second.budget_pool == budget_pool); 396 find_it->second.budget_pools.find(budget_pool) !=
397 find_it->second.budget_pools.end());
390 398
391 find_it->second.budget_pool = nullptr; 399 find_it->second.budget_pools.erase(budget_pool);
392 400
393 MaybeDeleteQueueMetadata(find_it); 401 MaybeDeleteQueueMetadata(find_it);
394 } 402 }
395 403
396 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) { 404 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) {
397 budget_pools_.erase(budget_pool); 405 budget_pools_.erase(budget_pool);
398 } 406 }
399 407
400 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) { 408 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) {
401 SchedulePumpQueue(FROM_HERE, now, queue); 409 SchedulePumpQueue(FROM_HERE, now, queue);
(...skipping 11 matching lines...) Expand all
413 NextTaskRunTime(&lazy_now, queue); 421 NextTaskRunTime(&lazy_now, queue);
414 if (!next_desired_run_time) 422 if (!next_desired_run_time)
415 return; 423 return;
416 424
417 base::Optional<base::TimeTicks> next_run_time = 425 base::Optional<base::TimeTicks> next_run_time =
418 Max(next_desired_run_time, GetNextAllowedRunTime(now, queue)); 426 Max(next_desired_run_time, GetNextAllowedRunTime(now, queue));
419 427
420 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value()); 428 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value());
421 } 429 }
422 430
423 BudgetPool* TaskQueueThrottler::GetBudgetPoolForQueue(TaskQueue* queue) {
424 auto find_it = queue_details_.find(queue);
425 if (find_it == queue_details_.end())
426 return nullptr;
427 return find_it->second.budget_pool;
428 }
429
430 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now, 431 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now,
431 TaskQueue* queue) { 432 TaskQueue* queue) {
432 BudgetPool* budget_pool = GetBudgetPoolForQueue(queue); 433 base::TimeTicks next_run_time = now;
433 if (!budget_pool) 434
434 return now; 435 auto find_it = queue_details_.find(queue);
435 return std::max(now, budget_pool->GetNextAllowedRunTime()); 436 if (find_it == queue_details_.end())
437 return next_run_time;
438
439 for (BudgetPool* budget_pool : find_it->second.budget_pools) {
440 next_run_time =
441 std::max(next_run_time, budget_pool->GetNextAllowedRunTime());
442 }
443
444 return next_run_time;
436 } 445 }
437 446
438 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { 447 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) {
439 if (it->second.throttling_ref_count == 0 && !it->second.budget_pool) 448 if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty())
440 queue_details_.erase(it); 449 queue_details_.erase(it);
441 } 450 }
442 451
443 void TaskQueueThrottler::DisableThrottling() { 452 void TaskQueueThrottler::DisableThrottling() {
444 if (!allow_throttling_) 453 if (!allow_throttling_)
445 return; 454 return;
446 455
447 allow_throttling_ = false; 456 allow_throttling_ = false;
448 457
449 for (const auto& map_entry : queue_details_) { 458 for (const auto& map_entry : queue_details_) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); 491 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
483 queue->SetTimeDomain(time_domain_.get()); 492 queue->SetTimeDomain(time_domain_.get());
484 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue); 493 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue);
485 } 494 }
486 495
487 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling"); 496 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling");
488 } 497 }
489 498
490 } // namespace scheduler 499 } // namespace scheduler
491 } // namespace blink 500 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698