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 "components/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 "components/scheduler/base/real_time_domain.h" | 11 #include "components/scheduler/base/real_time_domain.h" |
12 #include "components/scheduler/base/task_queue_impl.h" | 12 #include "components/scheduler/base/task_queue_impl.h" |
13 #include "components/scheduler/base/task_queue_manager_delegate.h" | 13 #include "components/scheduler/base/task_queue_manager_delegate.h" |
14 #include "components/scheduler/base/task_queue_selector.h" | 14 #include "components/scheduler/base/task_queue_selector.h" |
15 #include "components/scheduler/base/task_queue_sets.h" | 15 #include "components/scheduler/base/task_queue_sets.h" |
16 | 16 |
17 namespace scheduler { | 17 namespace scheduler { |
18 | 18 |
19 TaskQueueManager::TaskQueueManager( | 19 TaskQueueManager::TaskQueueManager( |
20 scoped_refptr<TaskQueueManagerDelegate> delegate, | 20 scoped_refptr<TaskQueueManagerDelegate> delegate, |
21 const char* tracing_category, | 21 const char* tracing_category, |
22 const char* disabled_by_default_tracing_category, | 22 const char* disabled_by_default_tracing_category, |
23 const char* disabled_by_default_verbose_tracing_category) | 23 const char* disabled_by_default_verbose_tracing_category) |
24 : real_time_domain_(new RealTimeDomain()), | 24 : delegate_(delegate), |
25 delegate_(delegate), | |
26 task_was_run_on_quiescence_monitored_queue_(false), | 25 task_was_run_on_quiescence_monitored_queue_(false), |
27 pending_dowork_count_(0), | 26 pending_dowork_count_(0), |
28 work_batch_size_(1), | 27 work_batch_size_(1), |
29 tracing_category_(tracing_category), | 28 tracing_category_(tracing_category), |
30 disabled_by_default_tracing_category_( | 29 disabled_by_default_tracing_category_( |
31 disabled_by_default_tracing_category), | 30 disabled_by_default_tracing_category), |
32 disabled_by_default_verbose_tracing_category_( | 31 disabled_by_default_verbose_tracing_category_( |
33 disabled_by_default_verbose_tracing_category), | 32 disabled_by_default_verbose_tracing_category), |
34 observer_(nullptr), | 33 observer_(nullptr), |
35 deletion_sentinel_(new DeletionSentinel()), | 34 deletion_sentinel_(new DeletionSentinel()), |
36 weak_factory_(this) { | 35 weak_factory_(this) { |
37 DCHECK(delegate->RunsTasksOnCurrentThread()); | 36 DCHECK(delegate->RunsTasksOnCurrentThread()); |
38 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, | 37 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, |
39 "TaskQueueManager", this); | 38 "TaskQueueManager", this); |
40 selector_.SetTaskQueueSelectorObserver(this); | 39 selector_.SetTaskQueueSelectorObserver(this); |
41 | 40 |
42 decrement_pending_and_do_work_closure_ = | 41 decrement_pending_and_do_work_closure_ = |
43 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); | 42 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); |
44 do_work_closure_ = | 43 do_work_closure_ = |
45 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); | 44 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); |
46 | 45 |
47 // TODO(alexclarke): Change this to be a parameter that's passed in. | 46 // TODO(alexclarke): Change this to be a parameter that's passed in. |
48 RegisterTimeDomain(real_time_domain_.get()); | 47 real_time_domain_ = make_scoped_refptr(new RealTimeDomain()); |
| 48 RegisterTimeDomain(real_time_domain_); |
49 } | 49 } |
50 | 50 |
51 TaskQueueManager::~TaskQueueManager() { | 51 TaskQueueManager::~TaskQueueManager() { |
52 TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_, | 52 TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_, |
53 "TaskQueueManager", this); | 53 "TaskQueueManager", this); |
54 | 54 |
55 while (!queues_.empty()) | 55 while (!queues_.empty()) |
56 (*queues_.begin())->UnregisterTaskQueue(); | 56 (*queues_.begin())->UnregisterTaskQueue(); |
57 | 57 |
58 selector_.SetTaskQueueSelectorObserver(nullptr); | 58 selector_.SetTaskQueueSelectorObserver(nullptr); |
59 } | 59 } |
60 | 60 |
61 void TaskQueueManager::RegisterTimeDomain(TimeDomain* time_domain) { | 61 void TaskQueueManager::RegisterTimeDomain( |
| 62 const scoped_refptr<TimeDomain>& time_domain) { |
62 time_domains_.insert(time_domain); | 63 time_domains_.insert(time_domain); |
63 time_domain->OnRegisterWithTaskQueueManager(delegate_.get(), | 64 time_domain->OnRegisterWithTaskQueueManager(delegate_.get(), |
64 do_work_closure_); | 65 do_work_closure_); |
65 } | 66 } |
66 | 67 |
67 void TaskQueueManager::UnregisterTimeDomain(TimeDomain* time_domain) { | 68 void TaskQueueManager::UnregisterTimeDomain( |
| 69 const scoped_refptr<TimeDomain>& time_domain) { |
68 time_domains_.erase(time_domain); | 70 time_domains_.erase(time_domain); |
69 } | 71 } |
70 | 72 |
71 scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue( | 73 scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue( |
72 const TaskQueue::Spec& spec) { | 74 const TaskQueue::Spec& spec) { |
73 TRACE_EVENT1(tracing_category_, | 75 TRACE_EVENT1(tracing_category_, |
74 "TaskQueueManager::NewTaskQueue", "queue_name", spec.name); | 76 "TaskQueueManager::NewTaskQueue", "queue_name", spec.name); |
75 DCHECK(main_thread_checker_.CalledOnValidThread()); | 77 DCHECK(main_thread_checker_.CalledOnValidThread()); |
76 TimeDomain* time_domain = | 78 TimeDomain* time_domain = |
77 spec.time_domain ? spec.time_domain : real_time_domain_.get(); | 79 spec.time_domain ? spec.time_domain : real_time_domain_.get(); |
78 DCHECK(time_domains_.find(time_domain) != time_domains_.end()); | 80 DCHECK(time_domains_.find(make_scoped_refptr(time_domain)) != |
| 81 time_domains_.end()); |
79 scoped_refptr<internal::TaskQueueImpl> queue( | 82 scoped_refptr<internal::TaskQueueImpl> queue( |
80 make_scoped_refptr(new internal::TaskQueueImpl( | 83 make_scoped_refptr(new internal::TaskQueueImpl( |
81 this, time_domain, spec, disabled_by_default_tracing_category_, | 84 this, time_domain, spec, disabled_by_default_tracing_category_, |
82 disabled_by_default_verbose_tracing_category_))); | 85 disabled_by_default_verbose_tracing_category_))); |
83 queues_.insert(queue); | 86 queues_.insert(queue); |
84 selector_.AddQueue(queue.get()); | 87 selector_.AddQueue(queue.get()); |
85 return queue; | 88 return queue; |
86 } | 89 } |
87 | 90 |
88 void TaskQueueManager::SetObserver(Observer* observer) { | 91 void TaskQueueManager::SetObserver(Observer* observer) { |
(...skipping 16 matching lines...) Expand all Loading... |
105 queues_.erase(task_queue); | 108 queues_.erase(task_queue); |
106 selector_.RemoveQueue(task_queue.get()); | 109 selector_.RemoveQueue(task_queue.get()); |
107 } | 110 } |
108 | 111 |
109 void TaskQueueManager::UpdateWorkQueues( | 112 void TaskQueueManager::UpdateWorkQueues( |
110 bool should_trigger_wakeup, | 113 bool should_trigger_wakeup, |
111 const internal::TaskQueueImpl::Task* previous_task) { | 114 const internal::TaskQueueImpl::Task* previous_task) { |
112 TRACE_EVENT0(disabled_by_default_tracing_category_, | 115 TRACE_EVENT0(disabled_by_default_tracing_category_, |
113 "TaskQueueManager::UpdateWorkQueues"); | 116 "TaskQueueManager::UpdateWorkQueues"); |
114 | 117 |
115 for (TimeDomain* time_domain : time_domains_) { | 118 for (const scoped_refptr<TimeDomain>& time_domain : time_domains_) { |
116 time_domain->UpdateWorkQueues(should_trigger_wakeup, previous_task); | 119 time_domain->UpdateWorkQueues(should_trigger_wakeup, previous_task); |
117 } | 120 } |
118 } | 121 } |
119 | 122 |
120 void TaskQueueManager::MaybePostDoWorkOnMainRunner() { | 123 void TaskQueueManager::MaybePostDoWorkOnMainRunner() { |
121 bool on_main_thread = delegate_->BelongsToCurrentThread(); | 124 bool on_main_thread = delegate_->BelongsToCurrentThread(); |
122 if (on_main_thread) { | 125 if (on_main_thread) { |
123 // We only want one pending DoWork posted from the main thread, or we risk | 126 // We only want one pending DoWork posted from the main thread, or we risk |
124 // an explosion of pending DoWorks which could starve out everything else. | 127 // an explosion of pending DoWorks which could starve out everything else. |
125 if (pending_dowork_count_ > 0) { | 128 if (pending_dowork_count_ > 0) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 if (!selector_.EnabledWorkQueuesEmpty() || TryAdvanceTimeDomains()) { | 182 if (!selector_.EnabledWorkQueuesEmpty() || TryAdvanceTimeDomains()) { |
180 MaybePostDoWorkOnMainRunner(); | 183 MaybePostDoWorkOnMainRunner(); |
181 } else { | 184 } else { |
182 // Tell the task runner we have no more work. | 185 // Tell the task runner we have no more work. |
183 delegate_->OnNoMoreImmediateWork(); | 186 delegate_->OnNoMoreImmediateWork(); |
184 } | 187 } |
185 } | 188 } |
186 | 189 |
187 bool TaskQueueManager::TryAdvanceTimeDomains() { | 190 bool TaskQueueManager::TryAdvanceTimeDomains() { |
188 bool can_advance = false; | 191 bool can_advance = false; |
189 for (TimeDomain* time_domain : time_domains_) { | 192 for (const scoped_refptr<TimeDomain>& time_domain : time_domains_) { |
190 can_advance |= time_domain->MaybeAdvanceTime(); | 193 can_advance |= time_domain->MaybeAdvanceTime(); |
191 } | 194 } |
192 return can_advance; | 195 return can_advance; |
193 } | 196 } |
194 | 197 |
195 bool TaskQueueManager::SelectQueueToService( | 198 bool TaskQueueManager::SelectQueueToService( |
196 internal::TaskQueueImpl** out_queue) { | 199 internal::TaskQueueImpl** out_queue) { |
197 bool should_run = selector_.SelectQueueToService(out_queue); | 200 bool should_run = selector_.SelectQueueToService(out_queue); |
198 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 201 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
199 disabled_by_default_tracing_category_, "TaskQueueManager", this, | 202 disabled_by_default_tracing_category_, "TaskQueueManager", this, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 } | 318 } |
316 | 319 |
317 void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { | 320 void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { |
318 DCHECK(main_thread_checker_.CalledOnValidThread()); | 321 DCHECK(main_thread_checker_.CalledOnValidThread()); |
319 // Only schedule DoWork if there's something to do. | 322 // Only schedule DoWork if there's something to do. |
320 if (!queue->work_queue().empty()) | 323 if (!queue->work_queue().empty()) |
321 MaybePostDoWorkOnMainRunner(); | 324 MaybePostDoWorkOnMainRunner(); |
322 } | 325 } |
323 | 326 |
324 } // namespace scheduler | 327 } // namespace scheduler |
OLD | NEW |