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