| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |