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 |