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/trace_event/blame_context.h" | 7 #include "base/trace_event/blame_context.h" |
8 #include "platform/scheduler/base/task_queue_manager.h" | 8 #include "platform/scheduler/base/task_queue_manager.h" |
9 #include "platform/scheduler/base/task_queue_manager_delegate.h" | 9 #include "platform/scheduler/base/task_queue_manager_delegate.h" |
10 #include "platform/scheduler/base/time_domain.h" | 10 #include "platform/scheduler/base/time_domain.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // contains a strong reference to this TaskQueueImpl and the TaskQueueManager | 44 // contains a strong reference to this TaskQueueImpl and the TaskQueueManager |
45 // destructor calls UnregisterTaskQueue on all task queues. | 45 // destructor calls UnregisterTaskQueue on all task queues. |
46 DCHECK(any_thread().task_queue_manager == nullptr) | 46 DCHECK(any_thread().task_queue_manager == nullptr) |
47 << "UnregisterTaskQueue must be called first!"; | 47 << "UnregisterTaskQueue must be called first!"; |
48 | 48 |
49 #endif | 49 #endif |
50 } | 50 } |
51 | 51 |
52 TaskQueueImpl::Task::Task() | 52 TaskQueueImpl::Task::Task() |
53 : PendingTask(tracked_objects::Location(), | 53 : PendingTask(tracked_objects::Location(), |
54 base::Closure(), | 54 base::OnceClosure(), |
55 base::TimeTicks(), | 55 base::TimeTicks(), |
56 true), | 56 true), |
57 #ifndef NDEBUG | 57 #ifndef NDEBUG |
58 enqueue_order_set_(false), | 58 enqueue_order_set_(false), |
59 #endif | 59 #endif |
60 enqueue_order_(0) { | 60 enqueue_order_(0) { |
61 sequence_num = 0; | 61 sequence_num = 0; |
62 } | 62 } |
63 | 63 |
64 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | 64 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, |
65 const base::Closure& task, | 65 base::OnceClosure task, |
66 base::TimeTicks desired_run_time, | 66 base::TimeTicks desired_run_time, |
67 EnqueueOrder sequence_number, | 67 EnqueueOrder sequence_number, |
68 bool nestable) | 68 bool nestable) |
69 : PendingTask(posted_from, task, desired_run_time, nestable), | 69 : PendingTask(posted_from, std::move(task), desired_run_time, nestable), |
70 #ifndef NDEBUG | 70 #ifndef NDEBUG |
71 enqueue_order_set_(false), | 71 enqueue_order_set_(false), |
72 #endif | 72 #endif |
73 enqueue_order_(0) { | 73 enqueue_order_(0) { |
74 sequence_num = sequence_number; | 74 sequence_num = sequence_number; |
75 } | 75 } |
76 | 76 |
77 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | 77 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, |
78 const base::Closure& task, | 78 base::OnceClosure task, |
79 base::TimeTicks desired_run_time, | 79 base::TimeTicks desired_run_time, |
80 EnqueueOrder sequence_number, | 80 EnqueueOrder sequence_number, |
81 bool nestable, | 81 bool nestable, |
82 EnqueueOrder enqueue_order) | 82 EnqueueOrder enqueue_order) |
83 : PendingTask(posted_from, task, desired_run_time, nestable), | 83 : PendingTask(posted_from, std::move(task), desired_run_time, nestable), |
84 #ifndef NDEBUG | 84 #ifndef NDEBUG |
85 enqueue_order_set_(true), | 85 enqueue_order_set_(true), |
86 #endif | 86 #endif |
87 enqueue_order_(enqueue_order) { | 87 enqueue_order_(enqueue_order) { |
88 sequence_num = sequence_number; | 88 sequence_num = sequence_number; |
89 } | 89 } |
90 | 90 |
91 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, | 91 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, |
92 TimeDomain* time_domain) | 92 TimeDomain* time_domain) |
93 : task_queue_manager(task_queue_manager), time_domain(time_domain) {} | 93 : task_queue_manager(task_queue_manager), time_domain(time_domain) {} |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 main_thread_only().delayed_work_queue.reset(); | 127 main_thread_only().delayed_work_queue.reset(); |
128 } | 128 } |
129 | 129 |
130 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { | 130 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { |
131 base::AutoLock lock(any_thread_lock_); | 131 base::AutoLock lock(any_thread_lock_); |
132 return base::PlatformThread::CurrentId() == thread_id_; | 132 return base::PlatformThread::CurrentId() == thread_id_; |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, | 136 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, |
137 const base::Closure& task, | 137 base::OnceClosure task, |
138 base::TimeDelta delay) { | 138 base::TimeDelta delay) { |
139 if (delay.is_zero()) | 139 if (delay.is_zero()) |
140 return PostImmediateTaskImpl(from_here, task, TaskType::NORMAL); | 140 return PostImmediateTaskImpl(from_here, std::move(task), TaskType::NORMAL); |
141 | 141 |
142 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); | 142 return PostDelayedTaskImpl( |
| 143 from_here, std::move(task), delay, TaskType::NORMAL); |
143 } | 144 } |
144 | 145 |
145 bool TaskQueueImpl::PostNonNestableDelayedTask( | 146 bool TaskQueueImpl::PostNonNestableDelayedTask( |
146 const tracked_objects::Location& from_here, | 147 const tracked_objects::Location& from_here, |
147 const base::Closure& task, | 148 base::OnceClosure task, |
148 base::TimeDelta delay) { | 149 base::TimeDelta delay) { |
149 if (delay.is_zero()) | 150 if (delay.is_zero()) { |
150 return PostImmediateTaskImpl(from_here, task, TaskType::NON_NESTABLE); | 151 return PostImmediateTaskImpl( |
| 152 from_here, std::move(task), TaskType::NON_NESTABLE); |
| 153 } |
151 | 154 |
152 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); | 155 return PostDelayedTaskImpl( |
| 156 from_here, std::move(task), delay, TaskType::NON_NESTABLE); |
153 } | 157 } |
154 | 158 |
155 bool TaskQueueImpl::PostImmediateTaskImpl( | 159 bool TaskQueueImpl::PostImmediateTaskImpl( |
156 const tracked_objects::Location& from_here, | 160 const tracked_objects::Location& from_here, |
157 const base::Closure& task, | 161 base::OnceClosure task, |
158 TaskType task_type) { | 162 TaskType task_type) { |
159 base::AutoLock lock(any_thread_lock_); | 163 base::AutoLock lock(any_thread_lock_); |
160 if (!any_thread().task_queue_manager) | 164 if (!any_thread().task_queue_manager) |
161 return false; | 165 return false; |
162 | 166 |
163 EnqueueOrder sequence_number = | 167 EnqueueOrder sequence_number = |
164 any_thread().task_queue_manager->GetNextSequenceNumber(); | 168 any_thread().task_queue_manager->GetNextSequenceNumber(); |
165 | 169 |
166 PushOntoImmediateIncomingQueueLocked( | 170 PushOntoImmediateIncomingQueueLocked( |
167 from_here, | 171 from_here, |
168 task, | 172 std::move(task), |
169 base::TimeTicks(), | 173 base::TimeTicks(), |
170 sequence_number, | 174 sequence_number, |
171 task_type != TaskType::NON_NESTABLE); | 175 task_type != TaskType::NON_NESTABLE); |
172 return true; | 176 return true; |
173 } | 177 } |
174 | 178 |
175 bool TaskQueueImpl::PostDelayedTaskImpl( | 179 bool TaskQueueImpl::PostDelayedTaskImpl( |
176 const tracked_objects::Location& from_here, | 180 const tracked_objects::Location& from_here, |
177 const base::Closure& task, | 181 base::OnceClosure task, |
178 base::TimeDelta delay, | 182 base::TimeDelta delay, |
179 TaskType task_type) { | 183 TaskType task_type) { |
180 DCHECK_GT(delay, base::TimeDelta()); | 184 DCHECK_GT(delay, base::TimeDelta()); |
181 if (base::PlatformThread::CurrentId() == thread_id_) { | 185 if (base::PlatformThread::CurrentId() == thread_id_) { |
182 // Lock-free fast path for delayed tasks posted from the main thread. | 186 // Lock-free fast path for delayed tasks posted from the main thread. |
183 if (!main_thread_only().task_queue_manager) | 187 if (!main_thread_only().task_queue_manager) |
184 return false; | 188 return false; |
185 | 189 |
186 EnqueueOrder sequence_number = | 190 EnqueueOrder sequence_number = |
187 main_thread_only().task_queue_manager->GetNextSequenceNumber(); | 191 main_thread_only().task_queue_manager->GetNextSequenceNumber(); |
188 | 192 |
189 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); | 193 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
190 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; | 194 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; |
191 PushOntoDelayedIncomingQueueFromMainThread( | 195 PushOntoDelayedIncomingQueueFromMainThread( |
192 Task(from_here, task, time_domain_delayed_run_time, sequence_number, | 196 Task(from_here, std::move(task), time_domain_delayed_run_time, sequence_
number, |
193 task_type != TaskType::NON_NESTABLE), | 197 task_type != TaskType::NON_NESTABLE), |
194 time_domain_now); | 198 time_domain_now); |
195 } else { | 199 } else { |
196 // NOTE posting a delayed task from a different thread is not expected to | 200 // NOTE posting a delayed task from a different thread is not expected to |
197 // be common. This pathway is less optimal than perhaps it could be | 201 // be common. This pathway is less optimal than perhaps it could be |
198 // because it causes two main thread tasks to be run. Should this | 202 // because it causes two main thread tasks to be run. Should this |
199 // assumption prove to be false in future, we may need to revisit this. | 203 // assumption prove to be false in future, we may need to revisit this. |
200 base::AutoLock lock(any_thread_lock_); | 204 base::AutoLock lock(any_thread_lock_); |
201 if (!any_thread().task_queue_manager) | 205 if (!any_thread().task_queue_manager) |
202 return false; | 206 return false; |
203 | 207 |
204 EnqueueOrder sequence_number = | 208 EnqueueOrder sequence_number = |
205 any_thread().task_queue_manager->GetNextSequenceNumber(); | 209 any_thread().task_queue_manager->GetNextSequenceNumber(); |
206 | 210 |
207 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); | 211 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); |
208 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; | 212 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; |
209 PushOntoDelayedIncomingQueueLocked( | 213 PushOntoDelayedIncomingQueueLocked( |
210 Task(from_here, task, time_domain_delayed_run_time, sequence_number, | 214 Task(from_here, std::move(task), time_domain_delayed_run_time, |
211 task_type != TaskType::NON_NESTABLE)); | 215 sequence_number, task_type != TaskType::NON_NESTABLE)); |
212 } | 216 } |
213 return true; | 217 return true; |
214 } | 218 } |
215 | 219 |
216 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( | 220 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( |
217 Task pending_task, base::TimeTicks now) { | 221 Task pending_task, base::TimeTicks now) { |
218 main_thread_only().task_queue_manager->DidQueueTask(pending_task); | 222 main_thread_only().task_queue_manager->DidQueueTask(pending_task); |
219 | 223 |
220 // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue. | 224 // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue. |
221 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; | 225 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
(...skipping 12 matching lines...) Expand all Loading... |
234 FROM_HERE, | 238 FROM_HERE, |
235 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, | 239 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, |
236 base::Passed(&pending_task)), | 240 base::Passed(&pending_task)), |
237 base::TimeTicks(), | 241 base::TimeTicks(), |
238 thread_hop_task_sequence_number, | 242 thread_hop_task_sequence_number, |
239 false); | 243 false); |
240 } | 244 } |
241 | 245 |
242 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( | 246 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
243 const tracked_objects::Location& posted_from, | 247 const tracked_objects::Location& posted_from, |
244 const base::Closure& task, | 248 base::OnceClosure task, |
245 base::TimeTicks desired_run_time, | 249 base::TimeTicks desired_run_time, |
246 EnqueueOrder sequence_number, | 250 EnqueueOrder sequence_number, |
247 bool nestable) { | 251 bool nestable) { |
248 if (any_thread().immediate_incoming_queue.empty()) | 252 if (any_thread().immediate_incoming_queue.empty()) |
249 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); | 253 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); |
250 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make | 254 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make |
251 // it run. | 255 // it run. |
252 if (any_thread().immediate_incoming_queue.empty()) { | 256 if (any_thread().immediate_incoming_queue.empty()) { |
253 // There's no point posting a DoWork for a disabled queue, however we can | 257 // There's no point posting a DoWork for a disabled queue, however we can |
254 // only tell if it's disabled from the main thread. | 258 // only tell if it's disabled from the main thread. |
255 if (base::PlatformThread::CurrentId() == thread_id_) { | 259 if (base::PlatformThread::CurrentId() == thread_id_) { |
256 if (main_thread_only().is_enabled && !BlockedByFenceLocked()) | 260 if (main_thread_only().is_enabled && !BlockedByFenceLocked()) |
257 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); | 261 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); |
258 } else { | 262 } else { |
259 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); | 263 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); |
260 } | 264 } |
261 } | 265 } |
262 any_thread().immediate_incoming_queue.emplace( | 266 any_thread().immediate_incoming_queue.emplace( |
263 posted_from, task, desired_run_time, sequence_number, nestable, sequence_n
umber); | 267 posted_from, std::move(task), desired_run_time, sequence_number, nestable,
sequence_number); |
264 any_thread().task_queue_manager->DidQueueTask( any_thread().immediate_incoming
_queue.back()); | 268 any_thread().task_queue_manager->DidQueueTask( any_thread().immediate_incoming
_queue.back()); |
265 TraceQueueSize(true); | 269 TraceQueueSize(true); |
266 } | 270 } |
267 | 271 |
268 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { | 272 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { |
269 DCHECK(main_thread_checker_.CalledOnValidThread()); | 273 DCHECK(main_thread_checker_.CalledOnValidThread()); |
270 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; | 274 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
271 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); | 275 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
272 // Make sure |delayed_run_time| isn't in the past. | 276 // Make sure |delayed_run_time| isn't in the past. |
273 if (delayed_run_time < time_domain_now) { | 277 if (delayed_run_time < time_domain_now) { |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 state->SetBoolean("is_cancelled", task.task.IsCancelled()); | 674 state->SetBoolean("is_cancelled", task.task.IsCancelled()); |
671 state->SetDouble( | 675 state->SetDouble( |
672 "delayed_run_time", | 676 "delayed_run_time", |
673 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 677 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
674 state->EndDictionary(); | 678 state->EndDictionary(); |
675 } | 679 } |
676 | 680 |
677 } // namespace internal | 681 } // namespace internal |
678 } // namespace scheduler | 682 } // namespace scheduler |
679 } // namespace blink | 683 } // namespace blink |
OLD | NEW |