Chromium Code Reviews| 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 "components/scheduler/base/task_queue_impl.h" | 5 #include "components/scheduler/base/task_queue_impl.h" |
| 6 | 6 |
| 7 #include "components/scheduler/base/task_queue_manager.h" | 7 #include "components/scheduler/base/task_queue_manager.h" |
| 8 #include "components/scheduler/base/task_queue_manager_delegate.h" | 8 #include "components/scheduler/base/task_queue_manager_delegate.h" |
| 9 #include "components/scheduler/base/time_domain.h" | |
| 9 | 10 |
| 10 namespace scheduler { | 11 namespace scheduler { |
| 11 namespace internal { | 12 namespace internal { |
| 12 | 13 |
| 13 TaskQueueImpl::TaskQueueImpl( | 14 TaskQueueImpl::TaskQueueImpl( |
| 14 TaskQueueManager* task_queue_manager, | 15 TaskQueueManager* task_queue_manager, |
| 16 const scoped_refptr<TimeDomain>& time_domain, | |
| 15 const Spec& spec, | 17 const Spec& spec, |
| 16 const char* disabled_by_default_tracing_category, | 18 const char* disabled_by_default_tracing_category, |
| 17 const char* disabled_by_default_verbose_tracing_category) | 19 const char* disabled_by_default_verbose_tracing_category) |
| 18 : thread_id_(base::PlatformThread::CurrentId()), | 20 : thread_id_(base::PlatformThread::CurrentId()), |
| 19 any_thread_(task_queue_manager, spec.pump_policy), | 21 any_thread_(task_queue_manager, spec.pump_policy, time_domain), |
| 20 name_(spec.name), | 22 name_(spec.name), |
| 21 disabled_by_default_tracing_category_( | 23 disabled_by_default_tracing_category_( |
| 22 disabled_by_default_tracing_category), | 24 disabled_by_default_tracing_category), |
| 23 disabled_by_default_verbose_tracing_category_( | 25 disabled_by_default_verbose_tracing_category_( |
| 24 disabled_by_default_verbose_tracing_category), | 26 disabled_by_default_verbose_tracing_category), |
| 25 main_thread_only_(task_queue_manager), | 27 main_thread_only_(task_queue_manager), |
| 26 wakeup_policy_(spec.wakeup_policy), | 28 wakeup_policy_(spec.wakeup_policy), |
| 27 should_monitor_quiescence_(spec.should_monitor_quiescence), | 29 should_monitor_quiescence_(spec.should_monitor_quiescence), |
| 28 should_notify_observers_(spec.should_notify_observers) {} | 30 should_notify_observers_(spec.should_notify_observers) { |
| 31 DCHECK(time_domain.get()); | |
| 32 } | |
| 29 | 33 |
| 30 TaskQueueImpl::~TaskQueueImpl() {} | 34 TaskQueueImpl::~TaskQueueImpl() {} |
| 31 | 35 |
| 32 TaskQueueImpl::Task::Task() | 36 TaskQueueImpl::Task::Task() |
| 33 : PendingTask(tracked_objects::Location(), | 37 : PendingTask(tracked_objects::Location(), |
| 34 base::Closure(), | 38 base::Closure(), |
| 35 base::TimeTicks(), | 39 base::TimeTicks(), |
| 36 true), | 40 true), |
| 37 #ifndef NDEBUG | 41 #ifndef NDEBUG |
| 38 enqueue_order_set_(false), | 42 enqueue_order_set_(false), |
| 39 #endif | 43 #endif |
| 40 enqueue_order_(0) { | 44 enqueue_order_(0) { |
| 41 sequence_num = 0; | 45 sequence_num = 0; |
| 42 } | 46 } |
| 43 | 47 |
| 44 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | 48 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, |
| 45 const base::Closure& task, | 49 const base::Closure& task, |
| 46 int sequence_number, | 50 int sequence_number, |
| 47 bool nestable) | 51 bool nestable) |
| 48 : PendingTask(posted_from, task, base::TimeTicks(), nestable), | 52 : PendingTask(posted_from, task, base::TimeTicks(), nestable), |
| 49 #ifndef NDEBUG | 53 #ifndef NDEBUG |
| 50 enqueue_order_set_(false), | 54 enqueue_order_set_(false), |
| 51 #endif | 55 #endif |
| 52 enqueue_order_(0) { | 56 enqueue_order_(0) { |
| 53 sequence_num = sequence_number; | 57 sequence_num = sequence_number; |
| 54 } | 58 } |
| 55 | 59 |
| 56 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, | 60 TaskQueueImpl::AnyThread::AnyThread( |
| 57 PumpPolicy pump_policy) | 61 TaskQueueManager* task_queue_manager, |
| 58 : task_queue_manager(task_queue_manager), pump_policy(pump_policy) {} | 62 PumpPolicy pump_policy, |
| 63 const scoped_refptr<TimeDomain>& time_domain) | |
| 64 : task_queue_manager(task_queue_manager), | |
| 65 pump_policy(pump_policy), | |
| 66 time_domain(time_domain) {} | |
| 59 | 67 |
| 60 TaskQueueImpl::AnyThread::~AnyThread() {} | 68 TaskQueueImpl::AnyThread::~AnyThread() {} |
| 61 | 69 |
| 62 TaskQueueImpl::MainThreadOnly::MainThreadOnly( | 70 TaskQueueImpl::MainThreadOnly::MainThreadOnly( |
| 63 TaskQueueManager* task_queue_manager) | 71 TaskQueueManager* task_queue_manager) |
| 64 : task_queue_manager(task_queue_manager), | 72 : task_queue_manager(task_queue_manager), |
| 65 set_index(0) {} | 73 set_index(0) {} |
| 66 | 74 |
| 67 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} | 75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} |
| 68 | 76 |
| 69 void TaskQueueImpl::UnregisterTaskQueue() { | 77 void TaskQueueImpl::UnregisterTaskQueue() { |
| 70 base::AutoLock lock(any_thread_lock_); | 78 base::AutoLock lock(any_thread_lock_); |
| 71 if (!any_thread().task_queue_manager) | 79 if (!any_thread().task_queue_manager) |
| 72 return; | 80 return; |
| 81 any_thread().time_domain->UnregisterQueue(this); | |
| 82 any_thread().time_domain = nullptr; | |
| 73 any_thread().task_queue_manager->UnregisterTaskQueue(this); | 83 any_thread().task_queue_manager->UnregisterTaskQueue(this); |
| 74 | 84 |
| 75 any_thread().task_queue_manager = nullptr; | 85 any_thread().task_queue_manager = nullptr; |
| 76 main_thread_only().task_queue_manager = nullptr; | 86 main_thread_only().task_queue_manager = nullptr; |
| 77 any_thread().delayed_task_queue = std::priority_queue<Task>(); | 87 any_thread().delayed_task_queue = std::priority_queue<Task>(); |
| 78 any_thread().incoming_queue = std::queue<Task>(); | 88 any_thread().incoming_queue = std::queue<Task>(); |
| 79 main_thread_only().work_queue = std::queue<Task>(); | 89 main_thread_only().work_queue = std::queue<Task>(); |
| 80 } | 90 } |
| 81 | 91 |
| 82 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { | 92 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 97 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); | 107 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); |
| 98 } | 108 } |
| 99 | 109 |
| 100 bool TaskQueueImpl::PostDelayedTaskAt( | 110 bool TaskQueueImpl::PostDelayedTaskAt( |
| 101 const tracked_objects::Location& from_here, | 111 const tracked_objects::Location& from_here, |
| 102 const base::Closure& task, | 112 const base::Closure& task, |
| 103 base::TimeTicks desired_run_time) { | 113 base::TimeTicks desired_run_time) { |
| 104 base::AutoLock lock(any_thread_lock_); | 114 base::AutoLock lock(any_thread_lock_); |
| 105 if (!any_thread().task_queue_manager) | 115 if (!any_thread().task_queue_manager) |
| 106 return false; | 116 return false; |
| 107 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | 117 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); |
| 108 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, | 118 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, |
| 109 TaskType::NORMAL); | 119 TaskType::NORMAL); |
| 110 } | 120 } |
| 111 | 121 |
| 112 bool TaskQueueImpl::PostDelayedTaskImpl( | 122 bool TaskQueueImpl::PostDelayedTaskImpl( |
| 113 const tracked_objects::Location& from_here, | 123 const tracked_objects::Location& from_here, |
| 114 const base::Closure& task, | 124 const base::Closure& task, |
| 115 base::TimeDelta delay, | 125 base::TimeDelta delay, |
| 116 TaskType task_type) { | 126 TaskType task_type) { |
| 117 base::AutoLock lock(any_thread_lock_); | 127 base::AutoLock lock(any_thread_lock_); |
| 118 if (!any_thread().task_queue_manager) | 128 if (!any_thread().task_queue_manager) |
| 119 return false; | 129 return false; |
| 120 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | 130 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); |
| 121 base::TimeTicks desired_run_time; | 131 base::TimeTicks desired_run_time; |
| 122 if (delay > base::TimeDelta()) | 132 if (delay > base::TimeDelta()) |
| 123 desired_run_time = lazy_now.Now() + delay; | 133 desired_run_time = lazy_now.Now() + delay; |
| 124 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, | 134 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, |
| 125 task_type); | 135 task_type); |
| 126 } | 136 } |
| 127 | 137 |
| 128 bool TaskQueueImpl::PostDelayedTaskLocked( | 138 bool TaskQueueImpl::PostDelayedTaskLocked( |
| 129 LazyNow* lazy_now, | 139 LazyNow* lazy_now, |
| 130 const tracked_objects::Location& from_here, | 140 const tracked_objects::Location& from_here, |
| 131 const base::Closure& task, | 141 const base::Closure& task, |
| 132 base::TimeTicks desired_run_time, | 142 base::TimeTicks desired_run_time, |
| 133 TaskType task_type) { | 143 TaskType task_type) { |
| 134 DCHECK(any_thread().task_queue_manager); | 144 DCHECK(any_thread().task_queue_manager); |
| 135 Task pending_task(from_here, task, | 145 Task pending_task(from_here, task, |
| 136 any_thread().task_queue_manager->GetNextSequenceNumber(), | 146 any_thread().task_queue_manager->GetNextSequenceNumber(), |
| 137 task_type != TaskType::NON_NESTABLE); | 147 task_type != TaskType::NON_NESTABLE); |
| 138 any_thread().task_queue_manager->DidQueueTask(pending_task); | 148 any_thread().task_queue_manager->DidQueueTask(pending_task); |
| 139 | 149 |
| 140 if (!desired_run_time.is_null()) { | 150 if (!desired_run_time.is_null()) { |
| 141 pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); | 151 pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); |
| 142 // TODO(alexclarke): consider emplace() when C++11 library features allowed. | 152 // TODO(alexclarke): consider emplace() when C++11 library features allowed. |
| 143 any_thread().delayed_task_queue.push(pending_task); | 153 any_thread().delayed_task_queue.push(pending_task); |
| 144 TraceQueueSize(true); | 154 TraceQueueSize(true); |
| 145 // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue. | 155 // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue. |
| 146 any_thread().task_queue_manager->ScheduleDelayedWork(this, desired_run_time, | 156 if (base::PlatformThread::CurrentId() == thread_id_) { |
| 147 lazy_now); | 157 any_thread().time_domain->ScheduleDelayedWork(this, desired_run_time, |
| 158 lazy_now); | |
| 159 } else { | |
| 160 // NOTE posting a delayed task from a different thread is not expected to | |
| 161 // be common. This pathway is less optimal than perhaps it could be | |
| 162 // because it causes two main thread tasks to be run. Should this | |
| 163 // assumption prove to be false in future, we may need to revisit this. | |
| 164 Task thread_hop_task( | |
| 165 FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, | |
| 166 desired_run_time), | |
| 167 any_thread().task_queue_manager->GetNextSequenceNumber(), true); | |
| 168 any_thread().task_queue_manager->DidQueueTask(thread_hop_task); | |
| 169 pending_task.set_enqueue_order(thread_hop_task.sequence_num); | |
| 170 EnqueueTaskLocked(thread_hop_task); | |
| 171 } | |
| 148 return true; | 172 return true; |
| 149 } | 173 } |
| 150 pending_task.set_enqueue_order(pending_task.sequence_num); | 174 pending_task.set_enqueue_order(pending_task.sequence_num); |
| 151 EnqueueTaskLocked(pending_task); | 175 EnqueueTaskLocked(pending_task); |
| 152 return true; | 176 return true; |
| 153 } | 177 } |
| 154 | 178 |
| 179 void TaskQueueImpl::ScheduleDelayedWorkTask(base::TimeTicks desired_run_time) { | |
|
Sami
2015/11/19 14:52:23
Should we be holding the any thread lock here? Als
alex clarke (OOO till 29th)
2015/11/19 15:57:14
Locking isn't needed here.
Sami
2015/11/19 16:11:20
Hmm? any_thread() asserts that we're holding the l
alex clarke (OOO till 29th)
2015/11/19 16:52:56
Seems daft to take a lock here. Instead I put it
| |
| 180 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); | |
| 181 any_thread().time_domain->ScheduleDelayedWork(this, desired_run_time, | |
| 182 &lazy_now); | |
| 183 } | |
| 184 | |
| 155 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { | 185 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { |
| 156 base::AutoLock lock(any_thread_lock_); | 186 base::AutoLock lock(any_thread_lock_); |
| 157 if (!any_thread().task_queue_manager) | 187 if (!any_thread().task_queue_manager) |
| 158 return; | 188 return; |
| 159 | 189 |
| 160 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); | 190 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); |
| 161 } | 191 } |
| 162 | 192 |
| 163 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( | 193 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( |
| 164 LazyNow* lazy_now) { | 194 LazyNow* lazy_now) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (any_thread().pump_policy == PumpPolicy::MANUAL) | 245 if (any_thread().pump_policy == PumpPolicy::MANUAL) |
| 216 return false; | 246 return false; |
| 217 if (any_thread().pump_policy == PumpPolicy::AFTER_WAKEUP && | 247 if (any_thread().pump_policy == PumpPolicy::AFTER_WAKEUP && |
| 218 (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task))) | 248 (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task))) |
| 219 return false; | 249 return false; |
| 220 if (any_thread().incoming_queue.empty()) | 250 if (any_thread().incoming_queue.empty()) |
| 221 return false; | 251 return false; |
| 222 return true; | 252 return true; |
| 223 } | 253 } |
| 224 | 254 |
| 225 bool TaskQueueImpl::NextPendingDelayedTaskRunTime( | |
| 226 base::TimeTicks* next_pending_delayed_task) { | |
| 227 base::AutoLock lock(any_thread_lock_); | |
| 228 if (any_thread().delayed_task_queue.empty()) | |
| 229 return false; | |
| 230 *next_pending_delayed_task = | |
| 231 any_thread().delayed_task_queue.top().delayed_run_time; | |
| 232 return true; | |
| 233 } | |
| 234 | |
| 235 void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, | 255 void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, |
| 236 bool should_trigger_wakeup, | 256 bool should_trigger_wakeup, |
| 237 const Task* previous_task) { | 257 const Task* previous_task) { |
| 238 DCHECK(main_thread_only().work_queue.empty()); | 258 DCHECK(main_thread_only().work_queue.empty()); |
| 239 base::AutoLock lock(any_thread_lock_); | 259 base::AutoLock lock(any_thread_lock_); |
| 240 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) | 260 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) |
| 241 return; | 261 return; |
| 242 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); | 262 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); |
| 243 std::swap(main_thread_only().work_queue, any_thread().incoming_queue); | 263 std::swap(main_thread_only().work_queue, any_thread().incoming_queue); |
| 244 // |any_thread().incoming_queue| is now empty so | 264 // |any_thread().incoming_queue| is now empty so TimeDomain::UpdateQueues |
| 245 // TaskQueueManager::UpdateQueues no longer needs to consider | 265 // no longer needs to consider this queue for reloading. |
| 246 // this queue for reloading. | 266 any_thread().time_domain->UnregisterAsUpdatableTaskQueue(this); |
| 247 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); | |
| 248 if (!main_thread_only().work_queue.empty()) { | 267 if (!main_thread_only().work_queue.empty()) { |
| 249 DCHECK(any_thread().task_queue_manager); | 268 DCHECK(any_thread().task_queue_manager); |
| 250 any_thread().task_queue_manager->selector_.GetTaskQueueSets()->OnPushQueue( | 269 any_thread().task_queue_manager->selector_.GetTaskQueueSets()->OnPushQueue( |
| 251 this); | 270 this); |
| 252 TraceQueueSize(true); | 271 TraceQueueSize(true); |
| 253 } | 272 } |
| 254 } | 273 } |
| 255 | 274 |
| 256 TaskQueueImpl::Task TaskQueueImpl::TakeTaskFromWorkQueue() { | 275 TaskQueueImpl::Task TaskQueueImpl::TakeTaskFromWorkQueue() { |
| 257 // TODO(alexclarke): consider std::move() when allowed. | 276 // TODO(alexclarke): consider std::move() when allowed. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 280 main_thread_only().work_queue.size() + | 299 main_thread_only().work_queue.size() + |
| 281 any_thread().delayed_task_queue.size()); | 300 any_thread().delayed_task_queue.size()); |
| 282 if (!is_locked) | 301 if (!is_locked) |
| 283 any_thread_lock_.Release(); | 302 any_thread_lock_.Release(); |
| 284 } | 303 } |
| 285 | 304 |
| 286 void TaskQueueImpl::EnqueueTaskLocked(const Task& pending_task) { | 305 void TaskQueueImpl::EnqueueTaskLocked(const Task& pending_task) { |
| 287 if (!any_thread().task_queue_manager) | 306 if (!any_thread().task_queue_manager) |
| 288 return; | 307 return; |
| 289 if (any_thread().incoming_queue.empty()) | 308 if (any_thread().incoming_queue.empty()) |
| 290 any_thread().task_queue_manager->RegisterAsUpdatableTaskQueue(this); | 309 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); |
| 291 if (any_thread().pump_policy == PumpPolicy::AUTO && | 310 if (any_thread().pump_policy == PumpPolicy::AUTO && |
| 292 any_thread().incoming_queue.empty()) { | 311 any_thread().incoming_queue.empty()) { |
| 293 any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); | 312 any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); |
| 294 } | 313 } |
| 295 // TODO(alexclarke): consider std::move() when allowed. | 314 // TODO(alexclarke): consider std::move() when allowed. |
| 296 any_thread().incoming_queue.push(pending_task); | 315 any_thread().incoming_queue.push(pending_task); |
| 297 TraceQueueSize(true); | 316 TraceQueueSize(true); |
| 298 } | 317 } |
| 299 | 318 |
| 300 void TaskQueueImpl::EnqueueDelayedTaskLocked(const Task& pending_task) { | 319 void TaskQueueImpl::EnqueueDelayedTaskLocked(const Task& pending_task) { |
|
Sami
2015/11/19 14:52:23
Not something for this patch but we should conside
alex clarke (OOO till 29th)
2015/11/19 15:57:14
Acknowledged.
| |
| 301 if (!any_thread().task_queue_manager) | 320 if (!any_thread().task_queue_manager) |
| 302 return; | 321 return; |
| 303 if (any_thread().incoming_queue.empty()) | 322 if (any_thread().incoming_queue.empty()) |
| 304 any_thread().task_queue_manager->RegisterAsUpdatableTaskQueue(this); | 323 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); |
| 324 if (any_thread().pump_policy == PumpPolicy::AUTO && | |
| 325 any_thread().incoming_queue.empty()) { | |
| 326 any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); | |
| 327 } | |
| 305 // TODO(alexclarke): consider std::move() when allowed. | 328 // TODO(alexclarke): consider std::move() when allowed. |
| 306 any_thread().incoming_queue.push(pending_task); | 329 any_thread().incoming_queue.push(pending_task); |
| 307 any_thread().incoming_queue.back().set_enqueue_order( | 330 any_thread().incoming_queue.back().set_enqueue_order( |
| 308 any_thread().task_queue_manager->GetNextSequenceNumber()); | 331 any_thread().task_queue_manager->GetNextSequenceNumber()); |
| 309 TraceQueueSize(true); | 332 TraceQueueSize(true); |
| 310 } | 333 } |
| 311 | 334 |
| 312 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { | 335 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { |
| 313 base::AutoLock lock(any_thread_lock_); | 336 base::AutoLock lock(any_thread_lock_); |
| 314 if (pump_policy == PumpPolicy::AUTO && | 337 if (pump_policy == PumpPolicy::AUTO && |
| 315 any_thread().pump_policy != PumpPolicy::AUTO) { | 338 any_thread().pump_policy != PumpPolicy::AUTO) { |
| 316 PumpQueueLocked(); | 339 PumpQueueLocked(); |
| 317 } | 340 } |
| 318 any_thread().pump_policy = pump_policy; | 341 any_thread().pump_policy = pump_policy; |
| 319 } | 342 } |
| 320 | 343 |
| 321 void TaskQueueImpl::PumpQueueLocked() { | 344 void TaskQueueImpl::PumpQueueLocked() { |
| 322 if (!any_thread().task_queue_manager) | 345 if (!any_thread().task_queue_manager) |
| 323 return; | 346 return; |
| 324 | 347 |
| 325 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | 348 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); |
| 326 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); | 349 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); |
| 327 | 350 |
| 328 bool was_empty = main_thread_only().work_queue.empty(); | 351 bool was_empty = main_thread_only().work_queue.empty(); |
| 329 while (!any_thread().incoming_queue.empty()) { | 352 while (!any_thread().incoming_queue.empty()) { |
| 330 // TODO(alexclarke): consider std::move() when allowed. | 353 // TODO(alexclarke): consider std::move() when allowed. |
| 331 main_thread_only().work_queue.push(any_thread().incoming_queue.front()); | 354 main_thread_only().work_queue.push(any_thread().incoming_queue.front()); |
| 332 any_thread().incoming_queue.pop(); | 355 any_thread().incoming_queue.pop(); |
| 333 } | 356 } |
| 334 // |incoming_queue| is now empty so TaskQueueManager::UpdateQueues no longer | 357 // |incoming_queue| is now empty so TimeDomain::UpdateQueues no longer needs |
| 335 // needs to consider this queue for reloading. | 358 // to consider this queue for reloading. |
| 336 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); | 359 any_thread().time_domain->UnregisterAsUpdatableTaskQueue(this); |
| 337 if (!main_thread_only().work_queue.empty()) { | 360 if (!main_thread_only().work_queue.empty()) { |
| 338 if (was_empty) { | 361 if (was_empty) { |
| 339 any_thread() | 362 any_thread() |
| 340 .task_queue_manager->selector_.GetTaskQueueSets() | 363 .task_queue_manager->selector_.GetTaskQueueSets() |
| 341 ->OnPushQueue(this); | 364 ->OnPushQueue(this); |
| 342 } | 365 } |
| 343 any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); | 366 any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); |
| 344 } | 367 } |
| 345 } | 368 } |
| 346 | 369 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 default: | 446 default: |
| 424 NOTREACHED(); | 447 NOTREACHED(); |
| 425 return nullptr; | 448 return nullptr; |
| 426 } | 449 } |
| 427 } | 450 } |
| 428 | 451 |
| 429 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { | 452 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
| 430 base::AutoLock lock(any_thread_lock_); | 453 base::AutoLock lock(any_thread_lock_); |
| 431 state->BeginDictionary(); | 454 state->BeginDictionary(); |
| 432 state->SetString("name", GetName()); | 455 state->SetString("name", GetName()); |
| 456 state->SetString("time_domain_name", any_thread().time_domain->GetName()); | |
| 433 state->SetString("pump_policy", PumpPolicyToString(any_thread().pump_policy)); | 457 state->SetString("pump_policy", PumpPolicyToString(any_thread().pump_policy)); |
| 434 state->SetString("wakeup_policy", WakeupPolicyToString(wakeup_policy_)); | 458 state->SetString("wakeup_policy", WakeupPolicyToString(wakeup_policy_)); |
| 435 bool verbose_tracing_enabled = false; | 459 bool verbose_tracing_enabled = false; |
| 436 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 460 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| 437 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); | 461 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); |
| 438 state->SetInteger("incoming_queue_size", any_thread().incoming_queue.size()); | 462 state->SetInteger("incoming_queue_size", any_thread().incoming_queue.size()); |
| 439 state->SetInteger("work_queue_size", main_thread_only().work_queue.size()); | 463 state->SetInteger("work_queue_size", main_thread_only().work_queue.size()); |
| 440 state->SetInteger("delayed_task_queue_size", | 464 state->SetInteger("delayed_task_queue_size", |
| 441 any_thread().delayed_task_queue.size()); | 465 any_thread().delayed_task_queue.size()); |
| 442 if (verbose_tracing_enabled) { | 466 if (verbose_tracing_enabled) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 } | 498 } |
| 475 | 499 |
| 476 void TaskQueueImpl::NotifyDidProcessTask( | 500 void TaskQueueImpl::NotifyDidProcessTask( |
| 477 const base::PendingTask& pending_task) { | 501 const base::PendingTask& pending_task) { |
| 478 DCHECK(should_notify_observers_); | 502 DCHECK(should_notify_observers_); |
| 479 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, | 503 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, |
| 480 main_thread_only().task_observers, | 504 main_thread_only().task_observers, |
| 481 DidProcessTask(pending_task)); | 505 DidProcessTask(pending_task)); |
| 482 } | 506 } |
| 483 | 507 |
| 508 void TaskQueueImpl::SetTimeDomain( | |
| 509 const scoped_refptr<TimeDomain>& time_domain) { | |
| 510 base::AutoLock lock(any_thread_lock_); | |
| 511 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 512 if (time_domain == any_thread().time_domain) | |
| 513 return; | |
| 514 | |
| 515 any_thread().time_domain->MigrateQueue(this, time_domain.get()); | |
| 516 any_thread().time_domain = time_domain; | |
| 517 } | |
| 518 | |
| 484 // static | 519 // static |
| 485 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, | 520 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, |
| 486 base::trace_event::TracedValue* state) { | 521 base::trace_event::TracedValue* state) { |
| 487 std::queue<Task> queue_copy(queue); | 522 std::queue<Task> queue_copy(queue); |
| 488 while (!queue_copy.empty()) { | 523 while (!queue_copy.empty()) { |
| 489 TaskAsValueInto(queue_copy.front(), state); | 524 TaskAsValueInto(queue_copy.front(), state); |
| 490 queue_copy.pop(); | 525 queue_copy.pop(); |
| 491 } | 526 } |
| 492 } | 527 } |
| 493 | 528 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 509 state->SetInteger("enqueue_order", task.enqueue_order()); | 544 state->SetInteger("enqueue_order", task.enqueue_order()); |
| 510 state->SetInteger("sequence_num", task.sequence_num); | 545 state->SetInteger("sequence_num", task.sequence_num); |
| 511 state->SetBoolean("nestable", task.nestable); | 546 state->SetBoolean("nestable", task.nestable); |
| 512 state->SetBoolean("is_high_res", task.is_high_res); | 547 state->SetBoolean("is_high_res", task.is_high_res); |
| 513 state->SetDouble( | 548 state->SetDouble( |
| 514 "delayed_run_time", | 549 "delayed_run_time", |
| 515 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 550 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
| 516 state->EndDictionary(); | 551 state->EndDictionary(); |
| 517 } | 552 } |
| 518 | 553 |
| 554 size_t TaskQueueImpl::IncomingQueueSizeForTest() const { | |
| 555 base::AutoLock lock(any_thread_lock_); | |
| 556 return any_thread().incoming_queue.size(); | |
| 557 } | |
| 558 | |
| 519 } // namespace internal | 559 } // namespace internal |
| 520 } // namespace scheduler | 560 } // namespace scheduler |
| OLD | NEW |