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

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

Issue 2483843002: Revert of [scheduler] Teach scheduler about audio state (Closed)
Patch Set: Rebase Created 4 years, 1 month 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"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/optional.h" 12 #include "base/optional.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "platform/scheduler/base/real_time_domain.h" 14 #include "platform/scheduler/base/real_time_domain.h"
15 #include "platform/scheduler/child/scheduler_tqm_delegate.h" 15 #include "platform/scheduler/child/scheduler_tqm_delegate.h"
16 #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h"
16 #include "platform/scheduler/renderer/renderer_scheduler_impl.h" 17 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
17 #include "platform/scheduler/renderer/throttled_time_domain.h" 18 #include "platform/scheduler/renderer/throttled_time_domain.h"
18 #include "platform/scheduler/renderer/web_frame_scheduler_impl.h" 19 #include "platform/scheduler/renderer/web_frame_scheduler_impl.h"
19 #include "public/platform/WebFrameScheduler.h" 20 #include "public/platform/WebFrameScheduler.h"
20 21
21 namespace blink { 22 namespace blink {
22 namespace scheduler { 23 namespace scheduler {
23 24
24 namespace { 25 namespace {
25 constexpr base::TimeDelta kMaxBudgetLevel = base::TimeDelta::FromSeconds(1); 26 constexpr base::TimeDelta kMaxBudgetLevel = base::TimeDelta::FromSeconds(1);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 return; 143 return;
143 is_enabled_ = false; 144 is_enabled_ = false;
144 145
145 for (TaskQueue* queue : associated_task_queues_) { 146 for (TaskQueue* queue : associated_task_queues_) {
146 if (!task_queue_throttler_->IsThrottled(queue)) 147 if (!task_queue_throttler_->IsThrottled(queue))
147 continue; 148 continue;
148 149
149 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, lazy_now->Now(), 150 task_queue_throttler_->MaybeSchedulePumpQueue(FROM_HERE, lazy_now->Now(),
150 queue, base::nullopt); 151 queue, base::nullopt);
151 } 152 }
152
153 // TODO(altimin): We need to disable TimeBudgetQueues here or they will
154 // regenerate extra time budget when they are disabled.
155 } 153 }
156 154
157 bool TaskQueueThrottler::TimeBudgetPool::IsThrottlingEnabled() const { 155 bool TaskQueueThrottler::TimeBudgetPool::IsThrottlingEnabled() const {
158 return is_enabled_; 156 return is_enabled_;
159 } 157 }
160 158
161 void TaskQueueThrottler::TimeBudgetPool::Close() { 159 void TaskQueueThrottler::TimeBudgetPool::Close() {
162 DCHECK_EQ(0u, associated_task_queues_.size()); 160 DCHECK_EQ(0u, associated_task_queues_.size());
163 161
164 task_queue_throttler_->time_budget_pools_.erase(this); 162 task_queue_throttler_->time_budget_pools_.erase(this);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 TaskQueueThrottler::TaskQueueThrottler( 254 TaskQueueThrottler::TaskQueueThrottler(
257 RendererSchedulerImpl* renderer_scheduler, 255 RendererSchedulerImpl* renderer_scheduler,
258 const char* tracing_category) 256 const char* tracing_category)
259 : task_runner_(renderer_scheduler->ControlTaskRunner()), 257 : task_runner_(renderer_scheduler->ControlTaskRunner()),
260 renderer_scheduler_(renderer_scheduler), 258 renderer_scheduler_(renderer_scheduler),
261 tick_clock_(renderer_scheduler->tick_clock()), 259 tick_clock_(renderer_scheduler->tick_clock()),
262 tracing_category_(tracing_category), 260 tracing_category_(tracing_category),
263 time_domain_(new ThrottledTimeDomain(this, tracing_category)), 261 time_domain_(new ThrottledTimeDomain(this, tracing_category)),
264 max_budget_level_(kMaxBudgetLevel), 262 max_budget_level_(kMaxBudgetLevel),
265 max_throttling_duration_(kMaxThrottlingDuration), 263 max_throttling_duration_(kMaxThrottlingDuration),
266 allow_throttling_(true), 264 virtual_time_(false),
267 weak_factory_(this) { 265 weak_factory_(this) {
268 pump_throttled_tasks_closure_.Reset(base::Bind( 266 pump_throttled_tasks_closure_.Reset(base::Bind(
269 &TaskQueueThrottler::PumpThrottledTasks, weak_factory_.GetWeakPtr())); 267 &TaskQueueThrottler::PumpThrottledTasks, weak_factory_.GetWeakPtr()));
270 forward_immediate_work_callback_ = 268 forward_immediate_work_callback_ =
271 base::Bind(&TaskQueueThrottler::OnTimeDomainHasImmediateWork, 269 base::Bind(&TaskQueueThrottler::OnTimeDomainHasImmediateWork,
272 weak_factory_.GetWeakPtr()); 270 weak_factory_.GetWeakPtr());
273 271
274 renderer_scheduler_->RegisterTimeDomain(time_domain_.get()); 272 renderer_scheduler_->RegisterTimeDomain(time_domain_.get());
275 } 273 }
276 274
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 if (!enabled) { 307 if (!enabled) {
310 task_queue->SetQueueEnabled(false); 308 task_queue->SetQueueEnabled(false);
311 MaybeSchedulePumpQueue(FROM_HERE, tick_clock_->NowTicks(), task_queue, 309 MaybeSchedulePumpQueue(FROM_HERE, tick_clock_->NowTicks(), task_queue,
312 base::nullopt); 310 base::nullopt);
313 } 311 }
314 } 312 }
315 313
316 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) { 314 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) {
317 DCHECK_NE(task_queue, task_runner_.get()); 315 DCHECK_NE(task_queue, task_runner_.get());
318 316
317 if (virtual_time_)
318 return;
319
319 std::pair<TaskQueueMap::iterator, bool> insert_result = 320 std::pair<TaskQueueMap::iterator, bool> insert_result =
320 queue_details_.insert(std::make_pair(task_queue, Metadata())); 321 queue_details_.insert(std::make_pair(task_queue, Metadata()));
321 322
322 if (!insert_result.first->second.IsThrottled()) { 323 if (!insert_result.first->second.IsThrottled()) {
323 // The insert was successful so we need to throttle the queue. 324 // The insert was successful so we need to throttle the queue.
324 insert_result.first->second.enabled = task_queue->IsQueueEnabled(); 325 insert_result.first->second.enabled = task_queue->IsQueueEnabled();
325 326
326 if (allow_throttling_) { 327 task_queue->SetTimeDomain(time_domain_.get());
327 task_queue->SetTimeDomain(time_domain_.get()); 328 task_queue->RemoveFence();
328 task_queue->RemoveFence(); 329 task_queue->SetQueueEnabled(false);
329 task_queue->SetQueueEnabled(false);
330 330
331 if (!task_queue->IsEmpty()) { 331 if (!task_queue->IsEmpty()) {
332 if (task_queue->HasPendingImmediateWork()) { 332 if (task_queue->HasPendingImmediateWork()) {
333 OnTimeDomainHasImmediateWork(task_queue); 333 OnTimeDomainHasImmediateWork(task_queue);
334 } else { 334 } else {
335 OnTimeDomainHasDelayedWork(task_queue); 335 OnTimeDomainHasDelayedWork(task_queue);
336 }
337 } 336 }
338 } 337 }
339 338
340 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueThrottled", 339 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueThrottled",
341 "task_queue", task_queue); 340 "task_queue", task_queue);
342 } 341 }
343 342
344 insert_result.first->second.throttling_ref_count++; 343 insert_result.first->second.throttling_ref_count++;
345 } 344 }
346 345
347 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { 346 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) {
347 if (virtual_time_)
348 return;
349
348 TaskQueueMap::iterator iter = queue_details_.find(task_queue); 350 TaskQueueMap::iterator iter = queue_details_.find(task_queue);
349 351
350 if (iter != queue_details_.end() && 352 if (iter != queue_details_.end() &&
351 --iter->second.throttling_ref_count == 0) { 353 --iter->second.throttling_ref_count == 0) {
352 bool enabled = iter->second.enabled; 354 bool enabled = iter->second.enabled;
353 355
354 MaybeDeleteQueueMetadata(iter); 356 MaybeDeleteQueueMetadata(iter);
355 357
356 if (allow_throttling_) { 358 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
357 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 359 task_queue->RemoveFence();
358 task_queue->RemoveFence(); 360 task_queue->SetQueueEnabled(enabled);
359 task_queue->SetQueueEnabled(enabled);
360 }
361 361
362 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUntrottled", 362 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUntrottled",
363 "task_queue", task_queue); 363 "task_queue", task_queue);
364 } 364 }
365 } 365 }
366 366
367 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const { 367 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const {
368 auto find_it = queue_details_.find(task_queue); 368 auto find_it = queue_details_.find(task_queue);
369 if (find_it == queue_details_.end()) 369 if (find_it == queue_details_.end())
370 return false; 370 return false;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 base::TimeTicks unthrottled_runtime) { 471 base::TimeTicks unthrottled_runtime) {
472 const base::TimeDelta one_second = base::TimeDelta::FromSeconds(1); 472 const base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
473 return unthrottled_runtime + one_second - 473 return unthrottled_runtime + one_second -
474 ((unthrottled_runtime - base::TimeTicks()) % one_second); 474 ((unthrottled_runtime - base::TimeTicks()) % one_second);
475 } 475 }
476 476
477 void TaskQueueThrottler::MaybeSchedulePumpThrottledTasks( 477 void TaskQueueThrottler::MaybeSchedulePumpThrottledTasks(
478 const tracked_objects::Location& from_here, 478 const tracked_objects::Location& from_here,
479 base::TimeTicks now, 479 base::TimeTicks now,
480 base::TimeTicks unaligned_runtime) { 480 base::TimeTicks unaligned_runtime) {
481 if (!allow_throttling_) 481 if (virtual_time_)
482 return; 482 return;
483 483
484 base::TimeTicks runtime = 484 base::TimeTicks runtime =
485 std::max(now, AlignedThrottledRunTime(unaligned_runtime)); 485 std::max(now, AlignedThrottledRunTime(unaligned_runtime));
486 486
487 // If there is a pending call to PumpThrottledTasks and it's sooner than 487 // If there is a pending call to PumpThrottledTasks and it's sooner than
488 // |runtime| then return. 488 // |runtime| then return.
489 if (pending_pump_throttled_tasks_runtime_ && 489 if (pending_pump_throttled_tasks_runtime_ &&
490 runtime >= pending_pump_throttled_tasks_runtime_.value()) { 490 runtime >= pending_pump_throttled_tasks_runtime_.value()) {
491 return; 491 return;
492 } 492 }
493 493
494 pending_pump_throttled_tasks_runtime_ = runtime; 494 pending_pump_throttled_tasks_runtime_ = runtime;
495 495
496 pump_throttled_tasks_closure_.Cancel(); 496 pump_throttled_tasks_closure_.Cancel();
497 497
498 base::TimeDelta delay = pending_pump_throttled_tasks_runtime_.value() - now; 498 base::TimeDelta delay = pending_pump_throttled_tasks_runtime_.value() - now;
499 TRACE_EVENT1(tracing_category_, 499 TRACE_EVENT1(tracing_category_,
500 "TaskQueueThrottler::MaybeSchedulePumpThrottledTasks", 500 "TaskQueueThrottler::MaybeSchedulePumpThrottledTasks",
501 "delay_till_next_pump_ms", delay.InMilliseconds()); 501 "delay_till_next_pump_ms", delay.InMilliseconds());
502 task_runner_->PostDelayedTask( 502 task_runner_->PostDelayedTask(
503 from_here, pump_throttled_tasks_closure_.callback(), delay); 503 from_here, pump_throttled_tasks_closure_.callback(), delay);
504 } 504 }
505 505
506 void TaskQueueThrottler::EnableVirtualTime() {
507 virtual_time_ = true;
508
509 pump_throttled_tasks_closure_.Cancel();
510
511 for (auto it = queue_details_.begin(); it != queue_details_.end();) {
512 TaskQueue* task_queue = it->first;
513 bool enabled = it->second.enabled;
514
515 if (!it->second.time_budget_pool) {
516 it = queue_details_.erase(it);
517 } else {
518 // Fall back to default values.
519 it->second.throttling_ref_count = 0;
520 it->second.enabled = false;
521 it++;
522 }
523
524 task_queue->SetTimeDomain(renderer_scheduler_->GetVirtualTimeDomain());
525 task_queue->RemoveFence();
526 task_queue->SetQueueEnabled(enabled);
527 }
528 }
529
506 TaskQueueThrottler::TimeBudgetPool* TaskQueueThrottler::CreateTimeBudgetPool( 530 TaskQueueThrottler::TimeBudgetPool* TaskQueueThrottler::CreateTimeBudgetPool(
507 const char* name) { 531 const char* name) {
508 TimeBudgetPool* time_budget_pool = 532 TimeBudgetPool* time_budget_pool =
509 new TimeBudgetPool(name, this, tick_clock_->NowTicks(), max_budget_level_, 533 new TimeBudgetPool(name, this, tick_clock_->NowTicks(), max_budget_level_,
510 max_throttling_duration_); 534 max_throttling_duration_);
511 time_budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); 535 time_budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool);
512 return time_budget_pool; 536 return time_budget_pool;
513 } 537 }
514 538
515 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, 539 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 if (!time_budget_pool) 597 if (!time_budget_pool)
574 return now; 598 return now;
575 return std::max(now, time_budget_pool->GetNextAllowedRunTime()); 599 return std::max(now, time_budget_pool->GetNextAllowedRunTime());
576 } 600 }
577 601
578 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { 602 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) {
579 if (!it->second.IsThrottled() && !it->second.time_budget_pool) 603 if (!it->second.IsThrottled() && !it->second.time_budget_pool)
580 queue_details_.erase(it); 604 queue_details_.erase(it);
581 } 605 }
582 606
583 void TaskQueueThrottler::DisableThrottling() {
584 if (!allow_throttling_)
585 return;
586
587 allow_throttling_ = false;
588
589 for (const auto& map_entry : queue_details_) {
590 if (!map_entry.second.IsThrottled())
591 continue;
592
593 TaskQueue* queue = map_entry.first;
594
595 queue->SetTimeDomain(renderer_scheduler_->GetActiveTimeDomain());
596
597 queue->RemoveFence();
598 queue->SetQueueEnabled(map_entry.second.enabled);
599 }
600 }
601
602 void TaskQueueThrottler::EnableThrottling() {
603 if (allow_throttling_)
604 return;
605
606 allow_throttling_ = true;
607
608 LazyNow lazy_now(tick_clock_);
609
610 for (const auto& map_entry : queue_details_) {
611 if (!map_entry.second.IsThrottled())
612 continue;
613
614 TaskQueue* queue = map_entry.first;
615
616 queue->SetQueueEnabled(false);
617 queue->SetTimeDomain(time_domain_.get());
618 MaybeSchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue,
619 GetNextAllowedRunTime(lazy_now.Now(), queue));
620 }
621 }
622
623 } // namespace scheduler 607 } // namespace scheduler
624 } // namespace blink 608 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698