| 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 |