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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc

Issue 2718293003: scheduler: Ensure consistent delayed task ordering between task queues (Closed)
Patch Set: Review 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/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/trace_event/blame_context.h" 10 #include "base/trace_event/blame_context.h"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 main_thread_only().task_queue_manager->DidQueueTask(pending_task); 275 main_thread_only().task_queue_manager->DidQueueTask(pending_task);
276 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 276 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
277 277
278 // If |pending_task| is at the head of the queue, then make sure a wakeup 278 // If |pending_task| is at the head of the queue, then make sure a wakeup
279 // is requested if the queue is enabled. Note we still want to schedule a 279 // is requested if the queue is enabled. Note we still want to schedule a
280 // wakeup even if blocked by a fence, because we'd break throttling logic 280 // wakeup even if blocked by a fence, because we'd break throttling logic
281 // otherwise. 281 // otherwise.
282 base::TimeTicks next_delayed_task = 282 base::TimeTicks next_delayed_task =
283 main_thread_only().delayed_incoming_queue.top().delayed_run_time; 283 main_thread_only().delayed_incoming_queue.top().delayed_run_time;
284 if (next_delayed_task == delayed_run_time && IsQueueEnabled()) { 284 if (next_delayed_task == delayed_run_time && IsQueueEnabled()) {
285 main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time, 285 main_thread_only().time_domain->ScheduleDelayedWork(
286 now); 286 this, {delayed_run_time, pending_task.sequence_num}, now);
287 } 287 }
288 288
289 TraceQueueSize(false); 289 TraceQueueSize(false);
290 } 290 }
291 291
292 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { 292 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
293 any_thread().task_queue_manager->DidQueueTask(pending_task); 293 any_thread().task_queue_manager->DidQueueTask(pending_task);
294 294
295 int thread_hop_task_sequence_number = 295 int thread_hop_task_sequence_number =
296 any_thread().task_queue_manager->GetNextSequenceNumber(); 296 any_thread().task_queue_manager->GetNextSequenceNumber();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 } 407 }
408 408
409 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { 409 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() {
410 // Note we don't scheduled a wakeup for disabled queues. 410 // Note we don't scheduled a wakeup for disabled queues.
411 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled()) 411 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled())
412 return base::nullopt; 412 return base::nullopt;
413 413
414 return main_thread_only().delayed_incoming_queue.top().delayed_run_time; 414 return main_thread_only().delayed_incoming_queue.top().delayed_run_time;
415 } 415 }
416 416
417 base::Optional<base::TimeTicks> TaskQueueImpl::WakeUpForDelayedWork( 417 base::Optional<TaskQueueImpl::DelayedWakeUp>
418 LazyNow* lazy_now) { 418 TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) {
419 // Enqueue all delayed tasks that should be running now, skipping any that 419 // Enqueue all delayed tasks that should be running now, skipping any that
420 // have been canceled. 420 // have been canceled.
421 while (!main_thread_only().delayed_incoming_queue.empty()) { 421 while (!main_thread_only().delayed_incoming_queue.empty()) {
422 Task& task = 422 Task& task =
423 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); 423 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top());
424 if (task.task.IsCancelled()) { 424 if (task.task.IsCancelled()) {
425 main_thread_only().delayed_incoming_queue.pop(); 425 main_thread_only().delayed_incoming_queue.pop();
426 continue; 426 continue;
427 } 427 }
428 if (task.delayed_run_time > lazy_now->Now()) 428 if (task.delayed_run_time > lazy_now->Now())
429 break; 429 break;
430 task.set_enqueue_order( 430 task.set_enqueue_order(
431 main_thread_only().task_queue_manager->GetNextSequenceNumber()); 431 main_thread_only().task_queue_manager->GetNextSequenceNumber());
432 main_thread_only().delayed_work_queue->Push(std::move(task)); 432 main_thread_only().delayed_work_queue->Push(std::move(task));
433 main_thread_only().delayed_incoming_queue.pop(); 433 main_thread_only().delayed_incoming_queue.pop();
434 } 434 }
435 435
436 // Make sure the next wake up is scheduled. 436 // Make sure the next wake up is scheduled.
437 if (!main_thread_only().delayed_incoming_queue.empty()) 437 if (!main_thread_only().delayed_incoming_queue.empty()) {
438 return main_thread_only().delayed_incoming_queue.top().delayed_run_time; 438 return DelayedWakeUp{
439 main_thread_only().delayed_incoming_queue.top().delayed_run_time,
440 main_thread_only().delayed_incoming_queue.top().sequence_num};
441 }
439 442
440 return base::nullopt; 443 return base::nullopt;
441 } 444 }
442 445
443 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { 446 void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
444 bool is_tracing; 447 bool is_tracing;
445 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, 448 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
446 &is_tracing); 449 &is_tracing);
447 if (!is_tracing) 450 if (!is_tracing)
448 return; 451 return;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 583
581 any_thread().time_domain = time_domain; 584 any_thread().time_domain = time_domain;
582 } 585 }
583 586
584 main_thread_only().time_domain->UnregisterQueue(this); 587 main_thread_only().time_domain->UnregisterQueue(this);
585 main_thread_only().time_domain = time_domain; 588 main_thread_only().time_domain = time_domain;
586 time_domain->RegisterQueue(this); 589 time_domain->RegisterQueue(this);
587 590
588 if (IsQueueEnabled() && !main_thread_only().delayed_incoming_queue.empty()) { 591 if (IsQueueEnabled() && !main_thread_only().delayed_incoming_queue.empty()) {
589 time_domain->ScheduleDelayedWork( 592 time_domain->ScheduleDelayedWork(
590 this, main_thread_only().delayed_incoming_queue.top().delayed_run_time, 593 this,
594 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
595 main_thread_only().delayed_incoming_queue.top().sequence_num},
591 time_domain->Now()); 596 time_domain->Now());
592 } 597 }
593 } 598 }
594 599
595 TimeDomain* TaskQueueImpl::GetTimeDomain() const { 600 TimeDomain* TaskQueueImpl::GetTimeDomain() const {
596 if (base::PlatformThread::CurrentId() == thread_id_) 601 if (base::PlatformThread::CurrentId() == thread_id_)
597 return main_thread_only().time_domain; 602 return main_thread_only().time_domain;
598 603
599 base::AutoLock lock(any_thread_lock_); 604 base::AutoLock lock(any_thread_lock_);
600 return any_thread().time_domain; 605 return any_thread().time_domain;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 base::AutoLock lock(any_thread_lock_); 815 base::AutoLock lock(any_thread_lock_);
811 immediate_queues_empty = any_thread().immediate_incoming_queue.empty(); 816 immediate_queues_empty = any_thread().immediate_incoming_queue.empty();
812 } 817 }
813 // Avoid holding the lock while we fire the notification. 818 // Avoid holding the lock while we fire the notification.
814 if (!immediate_queues_empty) 819 if (!immediate_queues_empty)
815 main_thread_only().time_domain->OnQueueHasImmediateWork(this); 820 main_thread_only().time_domain->OnQueueHasImmediateWork(this);
816 821
817 if (!main_thread_only().delayed_incoming_queue.empty()) { 822 if (!main_thread_only().delayed_incoming_queue.empty()) {
818 main_thread_only().time_domain->ScheduleDelayedWork( 823 main_thread_only().time_domain->ScheduleDelayedWork(
819 this, 824 this,
820 main_thread_only().delayed_incoming_queue.top().delayed_run_time, 825 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
826 main_thread_only().delayed_incoming_queue.top().sequence_num},
821 main_thread_only().time_domain->Now()); 827 main_thread_only().time_domain->Now());
822 } 828 }
823 // Note the selector calls TaskQueueManager::OnTaskQueueEnabled which posts 829 // Note the selector calls TaskQueueManager::OnTaskQueueEnabled which posts
824 // a DoWork if needed. 830 // a DoWork if needed.
825 main_thread_only().task_queue_manager->selector_.EnableQueue(this); 831 main_thread_only().task_queue_manager->selector_.EnableQueue(this);
826 } else { 832 } else {
827 if (!main_thread_only().delayed_incoming_queue.empty()) 833 if (!main_thread_only().delayed_incoming_queue.empty())
828 main_thread_only().time_domain->CancelDelayedWork(this); 834 main_thread_only().time_domain->CancelDelayedWork(this);
829 main_thread_only().task_queue_manager->selector_.DisableQueue(this); 835 main_thread_only().task_queue_manager->selector_.DisableQueue(this);
830 } 836 }
(...skipping 26 matching lines...) Expand all
857 main_thread_only().delayed_incoming_queue = std::move(remaining_tasks); 863 main_thread_only().delayed_incoming_queue = std::move(remaining_tasks);
858 864
859 // Re-schedule delayed call to WakeUpForDelayedWork if needed. 865 // Re-schedule delayed call to WakeUpForDelayedWork if needed.
860 if (main_thread_only().delayed_incoming_queue.empty()) { 866 if (main_thread_only().delayed_incoming_queue.empty()) {
861 main_thread_only().time_domain->CancelDelayedWork(this); 867 main_thread_only().time_domain->CancelDelayedWork(this);
862 } else if (first_task_runtime != 868 } else if (first_task_runtime !=
863 main_thread_only().delayed_incoming_queue.top().delayed_run_time) { 869 main_thread_only().delayed_incoming_queue.top().delayed_run_time) {
864 if (IsQueueEnabled()) { 870 if (IsQueueEnabled()) {
865 main_thread_only().time_domain->ScheduleDelayedWork( 871 main_thread_only().time_domain->ScheduleDelayedWork(
866 this, 872 this,
867 main_thread_only().delayed_incoming_queue.top().delayed_run_time, 873 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
874 main_thread_only().delayed_incoming_queue.top().sequence_num},
868 main_thread_only().time_domain->Now()); 875 main_thread_only().time_domain->Now());
869 } 876 }
870 } 877 }
871 } 878 }
872 879
873 void TaskQueueImpl::PushImmediateIncomingTaskForTest( 880 void TaskQueueImpl::PushImmediateIncomingTaskForTest(
874 TaskQueueImpl::Task&& task) { 881 TaskQueueImpl::Task&& task) {
875 base::AutoLock lock(any_thread_lock_); 882 base::AutoLock lock(any_thread_lock_);
876 any_thread().immediate_incoming_queue.push_back(std::move(task)); 883 any_thread().immediate_incoming_queue.push_back(std::move(task));
877 } 884 }
878 885
879 } // namespace internal 886 } // namespace internal
880 } // namespace scheduler 887 } // namespace scheduler
881 } // namespace blink 888 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698