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

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

Issue 2548483002: [scheduler] Account for disabling throttling in TaskQueueThrottler::IsThrottled (Closed)
Patch Set: Created 4 years 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 TaskQueue* queue) { 93 TaskQueue* queue) {
94 std::pair<TaskQueueMap::iterator, bool> insert_result = 94 std::pair<TaskQueueMap::iterator, bool> insert_result =
95 task_queue_throttler_->queue_details_.insert( 95 task_queue_throttler_->queue_details_.insert(
96 std::make_pair(queue, Metadata(0, queue->IsQueueEnabled()))); 96 std::make_pair(queue, Metadata(0, queue->IsQueueEnabled())));
97 Metadata& metadata = insert_result.first->second; 97 Metadata& metadata = insert_result.first->second;
98 DCHECK(!metadata.time_budget_pool); 98 DCHECK(!metadata.time_budget_pool);
99 metadata.time_budget_pool = this; 99 metadata.time_budget_pool = this;
100 100
101 associated_task_queues_.insert(queue); 101 associated_task_queues_.insert(queue);
102 102
103 if (!is_enabled_ || !metadata.IsThrottled()) 103 if (!is_enabled_ || !task_queue_throttler_->IsThrottled(queue))
104 return; 104 return;
105 105
106 queue->SetQueueEnabled(false); 106 queue->SetQueueEnabled(false);
107 107
108 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, now, queue, 108 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, now, queue,
109 GetNextAllowedRunTime()); 109 GetNextAllowedRunTime());
110 } 110 }
111 111
112 void TaskQueueThrottler::TimeBudgetPool::RemoveQueue(base::TimeTicks now, 112 void TaskQueueThrottler::TimeBudgetPool::RemoveQueue(base::TimeTicks now,
113 TaskQueue* queue) { 113 TaskQueue* queue) {
114 auto find_it = task_queue_throttler_->queue_details_.find(queue); 114 auto find_it = task_queue_throttler_->queue_details_.find(queue);
115 DCHECK(find_it != task_queue_throttler_->queue_details_.end() && 115 DCHECK(find_it != task_queue_throttler_->queue_details_.end() &&
116 find_it->second.time_budget_pool == this); 116 find_it->second.time_budget_pool == this);
117 find_it->second.time_budget_pool = nullptr; 117 find_it->second.time_budget_pool = nullptr;
118 bool is_throttled = find_it->second.IsThrottled(); 118 bool is_throttled = task_queue_throttler_->IsThrottled(queue);
119 119
120 task_queue_throttler_->MaybeDeleteQueueMetadata(find_it); 120 task_queue_throttler_->MaybeDeleteQueueMetadata(find_it);
121 associated_task_queues_.erase(queue); 121 associated_task_queues_.erase(queue);
122 122
123 if (!is_enabled_ || !is_throttled) 123 if (!is_enabled_ || !is_throttled)
124 return; 124 return;
125 125
126 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, now, queue, 126 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, now, queue,
127 base::nullopt); 127 base::nullopt);
128 } 128 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 base::Bind(&TaskQueueThrottler::OnTimeDomainHasImmediateWork, 286 base::Bind(&TaskQueueThrottler::OnTimeDomainHasImmediateWork,
287 weak_factory_.GetWeakPtr()); 287 weak_factory_.GetWeakPtr());
288 288
289 renderer_scheduler_->RegisterTimeDomain(time_domain_.get()); 289 renderer_scheduler_->RegisterTimeDomain(time_domain_.get());
290 } 290 }
291 291
292 TaskQueueThrottler::~TaskQueueThrottler() { 292 TaskQueueThrottler::~TaskQueueThrottler() {
293 // It's possible for queues to be still throttled, so we need to tidy up 293 // It's possible for queues to be still throttled, so we need to tidy up
294 // before unregistering the time domain. 294 // before unregistering the time domain.
295 for (const TaskQueueMap::value_type& map_entry : queue_details_) { 295 for (const TaskQueueMap::value_type& map_entry : queue_details_) {
296 if (map_entry.second.IsThrottled()) { 296 TaskQueue* task_queue = map_entry.first;
297 TaskQueue* task_queue = map_entry.first; 297 if (IsThrottled(task_queue)) {
298 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 298 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
299 task_queue->RemoveFence(); 299 task_queue->RemoveFence();
300 } 300 }
301 } 301 }
302 302
303 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get()); 303 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get());
304 } 304 }
305 305
306 void TaskQueueThrottler::SetQueueEnabled(TaskQueue* task_queue, bool enabled) { 306 void TaskQueueThrottler::SetQueueEnabled(TaskQueue* task_queue, bool enabled) {
307 TaskQueueMap::iterator find_it = queue_details_.find(task_queue); 307 TaskQueueMap::iterator find_it = queue_details_.find(task_queue);
308 308
309 if (find_it == queue_details_.end()) { 309 if (find_it == queue_details_.end()) {
310 task_queue->SetQueueEnabled(enabled); 310 task_queue->SetQueueEnabled(enabled);
311 return; 311 return;
312 } 312 }
313 313
314 find_it->second.enabled = enabled; 314 find_it->second.enabled = enabled;
315 315
316 if (!find_it->second.IsThrottled()) { 316 if (!IsThrottled(task_queue)) {
317 task_queue->SetQueueEnabled(enabled); 317 task_queue->SetQueueEnabled(enabled);
318 return; 318 return;
319 } 319 }
320 320
321 // We don't enable the queue here because it's throttled and there might be 321 // We don't enable the queue here because it's throttled and there might be
322 // tasks in it's work queue that would execute immediatly rather than after 322 // tasks in it's work queue that would execute immediatly rather than after
323 // PumpThrottledTasks runs. 323 // PumpThrottledTasks runs.
324 if (!enabled) { 324 if (!enabled) {
325 task_queue->SetQueueEnabled(false); 325 task_queue->SetQueueEnabled(false);
326 MaybeSchedulePumpQueue(FROM_HERE, tick_clock_->NowTicks(), task_queue, 326 MaybeSchedulePumpQueue(FROM_HERE, tick_clock_->NowTicks(), task_queue,
327 base::nullopt); 327 base::nullopt);
328 } 328 }
329 } 329 }
330 330
331 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) { 331 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) {
332 DCHECK_NE(task_queue, task_runner_.get()); 332 DCHECK_NE(task_queue, task_runner_.get());
333 333
334 std::pair<TaskQueueMap::iterator, bool> insert_result = 334 std::pair<TaskQueueMap::iterator, bool> insert_result = queue_details_.insert(
335 queue_details_.insert(std::make_pair(task_queue, Metadata())); 335 std::make_pair(task_queue, Metadata(0 /* ref_count */,
336 task_queue->IsQueueEnabled())));
336 337
337 if (!insert_result.first->second.IsThrottled()) { 338 if (insert_result.first->second.throttling_ref_count == 0) {
338 // The insert was successful so we need to throttle the queue.
339 insert_result.first->second.enabled = task_queue->IsQueueEnabled();
340
341 if (allow_throttling_) { 339 if (allow_throttling_) {
342 task_queue->SetTimeDomain(time_domain_.get()); 340 task_queue->SetTimeDomain(time_domain_.get());
343 task_queue->RemoveFence(); 341 task_queue->RemoveFence();
344 task_queue->SetQueueEnabled(false); 342 task_queue->SetQueueEnabled(false);
345 343
346 if (!task_queue->IsEmpty()) { 344 if (!task_queue->IsEmpty()) {
347 if (task_queue->HasPendingImmediateWork()) { 345 if (task_queue->HasPendingImmediateWork()) {
348 OnTimeDomainHasImmediateWork(task_queue); 346 OnTimeDomainHasImmediateWork(task_queue);
349 } else { 347 } else {
350 OnTimeDomainHasDelayedWork(task_queue); 348 OnTimeDomainHasDelayedWork(task_queue);
(...skipping 22 matching lines...) Expand all
373 task_queue->RemoveFence(); 371 task_queue->RemoveFence();
374 task_queue->SetQueueEnabled(enabled); 372 task_queue->SetQueueEnabled(enabled);
375 } 373 }
376 374
377 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUntrottled", 375 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUntrottled",
378 "task_queue", task_queue); 376 "task_queue", task_queue);
379 } 377 }
380 } 378 }
381 379
382 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const { 380 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const {
381 if (!allow_throttling_)
382 return false;
383
383 auto find_it = queue_details_.find(task_queue); 384 auto find_it = queue_details_.find(task_queue);
384 if (find_it == queue_details_.end()) 385 if (find_it == queue_details_.end())
385 return false; 386 return false;
386 return find_it->second.IsThrottled(); 387 return find_it->second.throttling_ref_count > 0;
387 } 388 }
388 389
389 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) { 390 void TaskQueueThrottler::UnregisterTaskQueue(TaskQueue* task_queue) {
390 LazyNow lazy_now(tick_clock_); 391 LazyNow lazy_now(tick_clock_);
391 auto find_it = queue_details_.find(task_queue); 392 auto find_it = queue_details_.find(task_queue);
392 393
393 if (find_it == queue_details_.end()) 394 if (find_it == queue_details_.end())
394 return; 395 return;
395 396
396 if (find_it->second.time_budget_pool) 397 if (find_it->second.time_budget_pool)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 void TaskQueueThrottler::PumpThrottledTasks() { 431 void TaskQueueThrottler::PumpThrottledTasks() {
431 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks"); 432 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks");
432 pending_pump_throttled_tasks_runtime_.reset(); 433 pending_pump_throttled_tasks_runtime_.reset();
433 434
434 LazyNow lazy_now(tick_clock_); 435 LazyNow lazy_now(tick_clock_);
435 base::Optional<base::TimeTicks> next_scheduled_delayed_task; 436 base::Optional<base::TimeTicks> next_scheduled_delayed_task;
436 437
437 for (const TaskQueueMap::value_type& map_entry : queue_details_) { 438 for (const TaskQueueMap::value_type& map_entry : queue_details_) {
438 TaskQueue* task_queue = map_entry.first; 439 TaskQueue* task_queue = map_entry.first;
439 if (!map_entry.second.enabled || task_queue->IsEmpty() || 440 if (!map_entry.second.enabled || task_queue->IsEmpty() ||
440 !map_entry.second.IsThrottled()) 441 !IsThrottled(task_queue))
441 continue; 442 continue;
442 443
443 // Don't enable queues whose budget pool doesn't allow them to run now. 444 // Don't enable queues whose budget pool doesn't allow them to run now.
444 base::TimeTicks next_allowed_run_time = 445 base::TimeTicks next_allowed_run_time =
445 GetNextAllowedRunTime(lazy_now.Now(), task_queue); 446 GetNextAllowedRunTime(lazy_now.Now(), task_queue);
446 base::Optional<base::TimeTicks> next_desired_run_time = 447 base::Optional<base::TimeTicks> next_desired_run_time =
447 NextTaskRunTime(&lazy_now, task_queue); 448 NextTaskRunTime(&lazy_now, task_queue);
448 449
449 if (next_desired_run_time && 450 if (next_desired_run_time &&
450 next_allowed_run_time > next_desired_run_time.value()) { 451 next_allowed_run_time > next_desired_run_time.value()) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 587
587 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now, 588 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now,
588 TaskQueue* queue) { 589 TaskQueue* queue) {
589 TimeBudgetPool* time_budget_pool = GetTimeBudgetPoolForQueue(queue); 590 TimeBudgetPool* time_budget_pool = GetTimeBudgetPoolForQueue(queue);
590 if (!time_budget_pool) 591 if (!time_budget_pool)
591 return now; 592 return now;
592 return std::max(now, time_budget_pool->GetNextAllowedRunTime()); 593 return std::max(now, time_budget_pool->GetNextAllowedRunTime());
593 } 594 }
594 595
595 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { 596 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) {
596 if (!it->second.IsThrottled() && !it->second.time_budget_pool) 597 if (it->second.throttling_ref_count == 0 && !it->second.time_budget_pool)
597 queue_details_.erase(it); 598 queue_details_.erase(it);
598 } 599 }
599 600
600 void TaskQueueThrottler::DisableThrottling() { 601 void TaskQueueThrottler::DisableThrottling() {
601 if (!allow_throttling_) 602 if (!allow_throttling_)
602 return; 603 return;
603 604
604 allow_throttling_ = false; 605 allow_throttling_ = false;
605 606
606 for (const auto& map_entry : queue_details_) { 607 for (const auto& map_entry : queue_details_) {
607 if (!map_entry.second.IsThrottled()) 608 if (map_entry.second.throttling_ref_count == 0)
608 continue; 609 continue;
609 610
610 TaskQueue* queue = map_entry.first; 611 TaskQueue* queue = map_entry.first;
611 612
612 queue->SetTimeDomain(renderer_scheduler_->GetActiveTimeDomain()); 613 queue->SetTimeDomain(renderer_scheduler_->GetActiveTimeDomain());
613 614
614 queue->RemoveFence(); 615 queue->RemoveFence();
615 queue->SetQueueEnabled(map_entry.second.enabled); 616 queue->SetQueueEnabled(map_entry.second.enabled);
616 } 617 }
617 618
618 pump_throttled_tasks_closure_.Cancel(); 619 pump_throttled_tasks_closure_.Cancel();
619 pending_pump_throttled_tasks_runtime_ = base::nullopt; 620 pending_pump_throttled_tasks_runtime_ = base::nullopt;
620 } 621 }
621 622
622 void TaskQueueThrottler::EnableThrottling() { 623 void TaskQueueThrottler::EnableThrottling() {
623 if (allow_throttling_) 624 if (allow_throttling_)
624 return; 625 return;
625 626
626 allow_throttling_ = true; 627 allow_throttling_ = true;
627 628
628 LazyNow lazy_now(tick_clock_); 629 LazyNow lazy_now(tick_clock_);
629 630
630 for (const auto& map_entry : queue_details_) { 631 for (const auto& map_entry : queue_details_) {
631 if (!map_entry.second.IsThrottled()) 632 if (map_entry.second.throttling_ref_count == 0)
632 continue; 633 continue;
633 634
634 TaskQueue* queue = map_entry.first; 635 TaskQueue* queue = map_entry.first;
635 636
636 queue->SetQueueEnabled(false); 637 queue->SetQueueEnabled(false);
637 queue->SetTimeDomain(time_domain_.get()); 638 queue->SetTimeDomain(time_domain_.get());
638 MaybeSchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue, 639 MaybeSchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue,
639 GetNextAllowedRunTime(lazy_now.Now(), queue)); 640 GetNextAllowedRunTime(lazy_now.Now(), queue));
640 } 641 }
641 } 642 }
642 643
643 } // namespace scheduler 644 } // namespace scheduler
644 } // namespace blink 645 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698