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

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

Issue 2742383005: [scheduler] Untangle BudgetPool from TaskQueueThrottler. (Closed)
Patch Set: Addressed comments from skyostil@ 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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_); 173 LazyNow lazy_now(tick_clock_);
174 auto find_it = queue_details_.find(task_queue); 174 auto find_it = queue_details_.find(task_queue);
175 175
176 if (find_it == queue_details_.end()) 176 if (find_it == queue_details_.end())
177 return; 177 return;
178 178
179 if (find_it->second.time_budget_pool) 179 if (find_it->second.budget_pool)
180 find_it->second.time_budget_pool->RemoveQueue(lazy_now.Now(), task_queue); 180 find_it->second.budget_pool->RemoveQueue(lazy_now.Now(), task_queue);
181 181
182 queue_details_.erase(find_it); 182 queue_details_.erase(find_it);
183 } 183 }
184 184
185 void TaskQueueThrottler::OnTimeDomainHasImmediateWork(TaskQueue* queue) { 185 void TaskQueueThrottler::OnTimeDomainHasImmediateWork(TaskQueue* queue) {
186 // Forward to the main thread if called from another thread 186 // Forward to the main thread if called from another thread
187 if (!task_runner_->RunsTasksOnCurrentThread()) { 187 if (!task_runner_->RunsTasksOnCurrentThread()) {
188 task_runner_->PostTask(FROM_HERE, 188 task_runner_->PostTask(FROM_HERE,
189 base::Bind(forward_immediate_work_callback_, queue)); 189 base::Bind(forward_immediate_work_callback_, queue));
190 return; 190 return;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 from_here, pump_throttled_tasks_closure_.callback(), delay); 308 from_here, pump_throttled_tasks_closure_.callback(), delay);
309 } 309 }
310 310
311 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool( 311 CPUTimeBudgetPool* TaskQueueThrottler::CreateCPUTimeBudgetPool(
312 const char* name, 312 const char* name,
313 base::Optional<base::TimeDelta> max_budget_level, 313 base::Optional<base::TimeDelta> max_budget_level,
314 base::Optional<base::TimeDelta> max_throttling_duration) { 314 base::Optional<base::TimeDelta> max_throttling_duration) {
315 CPUTimeBudgetPool* time_budget_pool = 315 CPUTimeBudgetPool* time_budget_pool =
316 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks(), 316 new CPUTimeBudgetPool(name, this, tick_clock_->NowTicks(),
317 max_budget_level, max_throttling_duration); 317 max_budget_level, max_throttling_duration);
318 time_budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool); 318 budget_pools_[time_budget_pool] = base::WrapUnique(time_budget_pool);
319 return time_budget_pool; 319 return time_budget_pool;
320 } 320 }
321 321
322 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue, 322 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue,
323 base::TimeTicks start_time, 323 base::TimeTicks start_time,
324 base::TimeTicks end_time) { 324 base::TimeTicks end_time) {
325 if (!IsThrottled(task_queue)) 325 if (!IsThrottled(task_queue))
326 return; 326 return;
327 327
328 CPUTimeBudgetPool* time_budget_pool = GetTimeBudgetPoolForQueue(task_queue); 328 BudgetPool* budget_pool = GetBudgetPoolForQueue(task_queue);
329 if (!time_budget_pool) 329 if (!budget_pool)
330 return; 330 return;
331 331
332 time_budget_pool->RecordTaskRunTime(start_time, end_time); 332 budget_pool->RecordTaskRunTime(start_time, end_time);
333 if (!time_budget_pool->HasEnoughBudgetToRun(end_time)) 333 if (!budget_pool->HasEnoughBudgetToRun(end_time))
334 time_budget_pool->BlockThrottledQueues(end_time); 334 budget_pool->BlockThrottledQueues(end_time);
335 }
336
337 void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) {
338 if (!IsThrottled(queue))
339 return;
340
341 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
342 SchedulePumpQueue(FROM_HERE, now, queue);
335 } 343 }
336 344
337 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state, 345 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state,
338 base::TimeTicks now) const { 346 base::TimeTicks now) const {
339 if (pending_pump_throttled_tasks_runtime_) { 347 if (pending_pump_throttled_tasks_runtime_) {
340 state->SetDouble( 348 state->SetDouble(
341 "next_throttled_tasks_pump_in_seconds", 349 "next_throttled_tasks_pump_in_seconds",
342 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF()); 350 (pending_pump_throttled_tasks_runtime_.value() - now).InSecondsF());
343 } 351 }
344 352
345 state->SetBoolean("allow_throttling", allow_throttling_); 353 state->SetBoolean("allow_throttling", allow_throttling_);
346 354
347 state->BeginDictionary("time_budget_pools"); 355 state->BeginDictionary("time_budget_pools");
348 for (const auto& map_entry : time_budget_pools_) { 356 for (const auto& map_entry : budget_pools_) {
349 BudgetPool* pool = map_entry.first; 357 BudgetPool* pool = map_entry.first;
350 pool->AsValueInto(state, now); 358 pool->AsValueInto(state, now);
351 } 359 }
352 state->EndDictionary(); 360 state->EndDictionary();
353 361
354 state->BeginDictionary("queue_details"); 362 state->BeginDictionary("queue_details");
355 for (const auto& map_entry : queue_details_) { 363 for (const auto& map_entry : queue_details_) {
356 state->BeginDictionaryWithCopiedName(PointerToId(map_entry.first)); 364 state->BeginDictionaryWithCopiedName(PointerToId(map_entry.first));
357 365
358 state->SetInteger("throttling_ref_count", 366 state->SetInteger("throttling_ref_count",
359 map_entry.second.throttling_ref_count); 367 map_entry.second.throttling_ref_count);
360 368
361 state->EndDictionary(); 369 state->EndDictionary();
362 } 370 }
363 state->EndDictionary(); 371 state->EndDictionary();
364 } 372 }
365 373
366 CPUTimeBudgetPool* TaskQueueThrottler::GetTimeBudgetPoolForQueue( 374 void TaskQueueThrottler::AddQueueToBudgetPool(TaskQueue* queue,
375 BudgetPool* budget_pool) {
376 std::pair<TaskQueueMap::iterator, bool> insert_result =
377 queue_details_.insert(std::make_pair(queue, Metadata()));
378
379 Metadata& metadata = insert_result.first->second;
380
381 DCHECK(!metadata.budget_pool);
382 metadata.budget_pool = budget_pool;
383 }
384
385 void TaskQueueThrottler::RemoveQueueFromBudgetPool(TaskQueue* queue,
386 BudgetPool* budget_pool) {
387 auto find_it = queue_details_.find(queue);
388 DCHECK(find_it != queue_details_.end() &&
389 find_it->second.budget_pool == budget_pool);
390
391 find_it->second.budget_pool = nullptr;
392
393 MaybeDeleteQueueMetadata(find_it);
394 }
395
396 void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) {
397 budget_pools_.erase(budget_pool);
398 }
399
400 void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) {
401 SchedulePumpQueue(FROM_HERE, now, queue);
402 }
403
404 void TaskQueueThrottler::SchedulePumpQueue(
405 const tracked_objects::Location& from_here,
406 base::TimeTicks now,
367 TaskQueue* queue) { 407 TaskQueue* queue) {
408 if (!IsThrottled(queue))
409 return;
410
411 LazyNow lazy_now(now);
412 base::Optional<base::TimeTicks> next_desired_run_time =
413 NextTaskRunTime(&lazy_now, queue);
414 if (!next_desired_run_time)
415 return;
416
417 base::Optional<base::TimeTicks> next_run_time =
418 Max(next_desired_run_time, GetNextAllowedRunTime(now, queue));
419
420 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value());
421 }
422
423 BudgetPool* TaskQueueThrottler::GetBudgetPoolForQueue(TaskQueue* queue) {
368 auto find_it = queue_details_.find(queue); 424 auto find_it = queue_details_.find(queue);
369 if (find_it == queue_details_.end()) 425 if (find_it == queue_details_.end())
370 return nullptr; 426 return nullptr;
371 return find_it->second.time_budget_pool; 427 return find_it->second.budget_pool;
372 }
373
374 void TaskQueueThrottler::MaybeSchedulePumpQueue(
375 const tracked_objects::Location& from_here,
376 base::TimeTicks now,
377 TaskQueue* queue,
378 base::Optional<base::TimeTicks> next_possible_run_time) {
379 LazyNow lazy_now(now);
380 base::Optional<base::TimeTicks> next_run_time =
381 Max(NextTaskRunTime(&lazy_now, queue), next_possible_run_time);
382
383 if (next_run_time) {
384 MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value());
385 }
386 } 428 }
387 429
388 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now, 430 base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now,
389 TaskQueue* queue) { 431 TaskQueue* queue) {
390 CPUTimeBudgetPool* time_budget_pool = GetTimeBudgetPoolForQueue(queue); 432 BudgetPool* budget_pool = GetBudgetPoolForQueue(queue);
391 if (!time_budget_pool) 433 if (!budget_pool)
392 return now; 434 return now;
393 return std::max(now, time_budget_pool->GetNextAllowedRunTime()); 435 return std::max(now, budget_pool->GetNextAllowedRunTime());
394 } 436 }
395 437
396 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) { 438 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) {
397 if (it->second.throttling_ref_count == 0 && !it->second.time_budget_pool) 439 if (it->second.throttling_ref_count == 0 && !it->second.budget_pool)
398 queue_details_.erase(it); 440 queue_details_.erase(it);
399 } 441 }
400 442
401 void TaskQueueThrottler::DisableThrottling() { 443 void TaskQueueThrottler::DisableThrottling() {
402 if (!allow_throttling_) 444 if (!allow_throttling_)
403 return; 445 return;
404 446
405 allow_throttling_ = false; 447 allow_throttling_ = false;
406 448
407 for (const auto& map_entry : queue_details_) { 449 for (const auto& map_entry : queue_details_) {
(...skipping 24 matching lines...) Expand all
432 for (const auto& map_entry : queue_details_) { 474 for (const auto& map_entry : queue_details_) {
433 if (map_entry.second.throttling_ref_count == 0) 475 if (map_entry.second.throttling_ref_count == 0)
434 continue; 476 continue;
435 477
436 TaskQueue* queue = map_entry.first; 478 TaskQueue* queue = map_entry.first;
437 479
438 // Throttling is enabled and task queue should be blocked immediately 480 // Throttling is enabled and task queue should be blocked immediately
439 // to enforce task alignment. 481 // to enforce task alignment.
440 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); 482 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
441 queue->SetTimeDomain(time_domain_.get()); 483 queue->SetTimeDomain(time_domain_.get());
442 MaybeSchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue, 484 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue);
443 GetNextAllowedRunTime(lazy_now.Now(), queue));
444 } 485 }
445 486
446 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling"); 487 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling");
447 } 488 }
448 489
449 } // namespace scheduler 490 } // namespace scheduler
450 } // namespace blink 491 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698