| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/scheduler/base/task_queue_manager.h" | 5 #include "platform/scheduler/base/task_queue_manager.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 13 #include "components/scheduler/base/real_time_domain.h" | 13 #include "platform/scheduler/base/real_time_domain.h" |
| 14 #include "components/scheduler/base/task_queue_impl.h" | 14 #include "platform/scheduler/base/task_queue_impl.h" |
| 15 #include "components/scheduler/base/task_queue_manager_delegate.h" | 15 #include "platform/scheduler/base/task_queue_manager_delegate.h" |
| 16 #include "components/scheduler/base/task_queue_selector.h" | 16 #include "platform/scheduler/base/task_queue_selector.h" |
| 17 #include "components/scheduler/base/task_time_tracker.h" | 17 #include "platform/scheduler/base/task_time_tracker.h" |
| 18 #include "components/scheduler/base/work_queue.h" | 18 #include "platform/scheduler/base/work_queue.h" |
| 19 #include "components/scheduler/base/work_queue_sets.h" | 19 #include "platform/scheduler/base/work_queue_sets.h" |
| 20 | 20 |
| 21 namespace blink { |
| 21 namespace scheduler { | 22 namespace scheduler { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10; | 25 const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10; |
| 25 | 26 |
| 26 void RecordDelayedTaskLateness(base::TimeDelta lateness) { | 27 void RecordDelayedTaskLateness(base::TimeDelta lateness) { |
| 27 UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness", | 28 UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness", |
| 28 lateness); | 29 lateness); |
| 29 } | 30 } |
| 30 | 31 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 time_domains_.insert(time_domain); | 86 time_domains_.insert(time_domain); |
| 86 time_domain->OnRegisterWithTaskQueueManager(this); | 87 time_domain->OnRegisterWithTaskQueueManager(this); |
| 87 } | 88 } |
| 88 | 89 |
| 89 void TaskQueueManager::UnregisterTimeDomain(TimeDomain* time_domain) { | 90 void TaskQueueManager::UnregisterTimeDomain(TimeDomain* time_domain) { |
| 90 time_domains_.erase(time_domain); | 91 time_domains_.erase(time_domain); |
| 91 } | 92 } |
| 92 | 93 |
| 93 scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue( | 94 scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue( |
| 94 const TaskQueue::Spec& spec) { | 95 const TaskQueue::Spec& spec) { |
| 95 TRACE_EVENT1(tracing_category_, | 96 TRACE_EVENT1(tracing_category_, "TaskQueueManager::NewTaskQueue", |
| 96 "TaskQueueManager::NewTaskQueue", "queue_name", spec.name); | 97 "queue_name", spec.name); |
| 97 DCHECK(main_thread_checker_.CalledOnValidThread()); | 98 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 98 TimeDomain* time_domain = | 99 TimeDomain* time_domain = |
| 99 spec.time_domain ? spec.time_domain : real_time_domain_.get(); | 100 spec.time_domain ? spec.time_domain : real_time_domain_.get(); |
| 100 DCHECK(time_domains_.find(time_domain) != time_domains_.end()); | 101 DCHECK(time_domains_.find(time_domain) != time_domains_.end()); |
| 101 scoped_refptr<internal::TaskQueueImpl> queue( | 102 scoped_refptr<internal::TaskQueueImpl> queue( |
| 102 make_scoped_refptr(new internal::TaskQueueImpl( | 103 make_scoped_refptr(new internal::TaskQueueImpl( |
| 103 this, time_domain, spec, disabled_by_default_tracing_category_, | 104 this, time_domain, spec, disabled_by_default_tracing_category_, |
| 104 disabled_by_default_verbose_tracing_category_))); | 105 disabled_by_default_verbose_tracing_category_))); |
| 105 queues_.insert(queue); | 106 queues_.insert(queue); |
| 106 selector_.AddQueue(queue.get()); | 107 selector_.AddQueue(queue.get()); |
| 107 return queue; | 108 return queue; |
| 108 } | 109 } |
| 109 | 110 |
| 110 void TaskQueueManager::SetObserver(Observer* observer) { | 111 void TaskQueueManager::SetObserver(Observer* observer) { |
| 111 DCHECK(main_thread_checker_.CalledOnValidThread()); | 112 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 112 observer_ = observer; | 113 observer_ = observer; |
| 113 } | 114 } |
| 114 | 115 |
| 115 void TaskQueueManager::UnregisterTaskQueue( | 116 void TaskQueueManager::UnregisterTaskQueue( |
| 116 scoped_refptr<internal::TaskQueueImpl> task_queue) { | 117 scoped_refptr<internal::TaskQueueImpl> task_queue) { |
| 117 TRACE_EVENT1(tracing_category_, | 118 TRACE_EVENT1(tracing_category_, "TaskQueueManager::UnregisterTaskQueue", |
| 118 "TaskQueueManager::UnregisterTaskQueue", "queue_name", | 119 "queue_name", task_queue->GetName()); |
| 119 task_queue->GetName()); | |
| 120 DCHECK(main_thread_checker_.CalledOnValidThread()); | 120 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 121 if (observer_) | 121 if (observer_) |
| 122 observer_->OnUnregisterTaskQueue(task_queue); | 122 observer_->OnUnregisterTaskQueue(task_queue); |
| 123 | 123 |
| 124 // Add |task_queue| to |queues_to_delete_| so we can prevent it from being | 124 // Add |task_queue| to |queues_to_delete_| so we can prevent it from being |
| 125 // freed while any of our structures hold hold a raw pointer to it. | 125 // freed while any of our structures hold hold a raw pointer to it. |
| 126 queues_to_delete_.insert(task_queue); | 126 queues_to_delete_.insert(task_queue); |
| 127 queues_.erase(task_queue); | 127 queues_.erase(task_queue); |
| 128 selector_.RemoveQueue(task_queue.get()); | 128 selector_.RemoveQueue(task_queue.get()); |
| 129 } | 129 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 228 } |
| 229 | 229 |
| 230 lazy_now = real_time_domain()->CreateLazyNow(); | 230 lazy_now = real_time_domain()->CreateLazyNow(); |
| 231 if (!delegate_->IsNested() && task_time_tracker_) { | 231 if (!delegate_->IsNested() && task_time_tracker_) { |
| 232 // Only report top level task durations. | 232 // Only report top level task durations. |
| 233 base::TimeTicks task_end_time = lazy_now.Now(); | 233 base::TimeTicks task_end_time = lazy_now.Now(); |
| 234 task_time_tracker_->ReportTaskTime(task_start_time, task_end_time); | 234 task_time_tracker_->ReportTaskTime(task_start_time, task_end_time); |
| 235 task_start_time = task_end_time; | 235 task_start_time = task_end_time; |
| 236 } | 236 } |
| 237 | 237 |
| 238 work_queue = nullptr; // The queue may have been unregistered. | 238 work_queue = nullptr; // The queue may have been unregistered. |
| 239 | 239 |
| 240 UpdateWorkQueues(should_trigger_wakeup, &previous_task, lazy_now); | 240 UpdateWorkQueues(should_trigger_wakeup, &previous_task, lazy_now); |
| 241 | 241 |
| 242 // Only run a single task per batch in nested run loops so that we can | 242 // Only run a single task per batch in nested run loops so that we can |
| 243 // properly exit the nested loop when someone calls RunLoop::Quit(). | 243 // properly exit the nested loop when someone calls RunLoop::Quit(). |
| 244 if (delegate_->IsNested()) | 244 if (delegate_->IsNested()) |
| 245 break; | 245 break; |
| 246 } | 246 } |
| 247 | 247 |
| 248 // TODO(alexclarke): Consider refactoring the above loop to terminate only | 248 // TODO(alexclarke): Consider refactoring the above loop to terminate only |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 | 297 |
| 298 MaybeRecordTaskDelayHistograms(pending_task, queue); | 298 MaybeRecordTaskDelayHistograms(pending_task, queue); |
| 299 | 299 |
| 300 TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue", | 300 TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue", |
| 301 pending_task); | 301 pending_task); |
| 302 if (queue->GetShouldNotifyObservers()) { | 302 if (queue->GetShouldNotifyObservers()) { |
| 303 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_, | 303 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_, |
| 304 WillProcessTask(pending_task)); | 304 WillProcessTask(pending_task)); |
| 305 queue->NotifyWillProcessTask(pending_task); | 305 queue->NotifyWillProcessTask(pending_task); |
| 306 } | 306 } |
| 307 TRACE_EVENT1(tracing_category_, | 307 TRACE_EVENT1(tracing_category_, "TaskQueueManager::RunTask", "queue", |
| 308 "TaskQueueManager::RunTask", "queue", queue->GetName()); | 308 queue->GetName()); |
| 309 // NOTE when TaskQueues get unregistered a reference ends up getting retained | 309 // NOTE when TaskQueues get unregistered a reference ends up getting retained |
| 310 // by |queues_to_delete_| which is cleared at the top of |DoWork|. This means | 310 // by |queues_to_delete_| which is cleared at the top of |DoWork|. This means |
| 311 // we are OK to use raw pointers here. | 311 // we are OK to use raw pointers here. |
| 312 internal::TaskQueueImpl* prev_executing_task_queue = | 312 internal::TaskQueueImpl* prev_executing_task_queue = |
| 313 currently_executing_task_queue_; | 313 currently_executing_task_queue_; |
| 314 currently_executing_task_queue_ = queue; | 314 currently_executing_task_queue_ = queue; |
| 315 task_annotator_.RunTask("TaskQueueManager::PostTask", pending_task); | 315 task_annotator_.RunTask("TaskQueueManager::PostTask", pending_task); |
| 316 | 316 |
| 317 // Detect if the TaskQueueManager just got deleted. If this happens we must | 317 // Detect if the TaskQueueManager just got deleted. If this happens we must |
| 318 // not access any member variables after this point. | 318 // not access any member variables after this point. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 internal::WorkQueue* work_queue) { | 433 internal::WorkQueue* work_queue) { |
| 434 DCHECK(main_thread_checker_.CalledOnValidThread()); | 434 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 435 DCHECK(!work_queue->Empty()); | 435 DCHECK(!work_queue->Empty()); |
| 436 if (observer_) { | 436 if (observer_) { |
| 437 observer_->OnTriedToExecuteBlockedTask(*work_queue->task_queue(), | 437 observer_->OnTriedToExecuteBlockedTask(*work_queue->task_queue(), |
| 438 *work_queue->GetFrontTask()); | 438 *work_queue->GetFrontTask()); |
| 439 } | 439 } |
| 440 } | 440 } |
| 441 | 441 |
| 442 } // namespace scheduler | 442 } // namespace scheduler |
| 443 } // namespace blink |
| OLD | NEW |