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/child/task_queue_impl.h" | 5 #include "components/scheduler/child/task_queue_impl.h" |
| 6 | 6 |
| 7 #include "components/scheduler/child/task_queue_manager.h" | 7 #include "components/scheduler/child/task_queue_manager.h" |
| 8 | 8 |
| 9 namespace scheduler { | 9 namespace scheduler { |
| 10 namespace internal { | 10 namespace internal { |
| 11 | 11 |
| 12 SchedulerTask::SchedulerTask() | |
| 13 : PendingTask(tracked_objects::Location(), base::Closure()) {} | |
|
Sami
2015/08/05 11:27:34
Should we initialize age here and below?
alex clarke (OOO till 29th)
2015/08/05 14:32:43
Done.
| |
| 14 | |
| 15 SchedulerTask::SchedulerTask(const tracked_objects::Location& posted_from, | |
| 16 const base::Closure& task, | |
| 17 bool nestable) | |
| 18 : PendingTask(posted_from, task, base::TimeTicks(), nestable) {} | |
| 19 | |
| 12 TaskQueueImpl::TaskQueueImpl( | 20 TaskQueueImpl::TaskQueueImpl( |
| 13 TaskQueueManager* task_queue_manager, | 21 TaskQueueManager* task_queue_manager, |
| 14 const Spec& spec, | 22 const Spec& spec, |
| 15 const char* disabled_by_default_tracing_category, | 23 const char* disabled_by_default_tracing_category, |
| 16 const char* disabled_by_default_verbose_tracing_category) | 24 const char* disabled_by_default_verbose_tracing_category) |
| 17 : thread_id_(base::PlatformThread::CurrentId()), | 25 : thread_id_(base::PlatformThread::CurrentId()), |
| 18 task_queue_manager_(task_queue_manager), | 26 task_queue_manager_(task_queue_manager), |
| 19 pump_policy_(spec.pump_policy), | 27 pump_policy_(spec.pump_policy), |
| 20 delayed_task_sequence_number_(0), | |
| 21 name_(spec.name), | 28 name_(spec.name), |
| 22 disabled_by_default_tracing_category_( | 29 disabled_by_default_tracing_category_( |
| 23 disabled_by_default_tracing_category), | 30 disabled_by_default_tracing_category), |
| 24 disabled_by_default_verbose_tracing_category_( | 31 disabled_by_default_verbose_tracing_category_( |
| 25 disabled_by_default_verbose_tracing_category), | 32 disabled_by_default_verbose_tracing_category), |
| 26 wakeup_policy_(spec.wakeup_policy), | 33 wakeup_policy_(spec.wakeup_policy), |
| 27 set_index_(0), | 34 set_index_(0), |
| 28 should_monitor_quiescence_(spec.should_monitor_quiescence), | 35 should_monitor_quiescence_(spec.should_monitor_quiescence), |
| 29 should_notify_observers_(spec.should_notify_observers) {} | 36 should_notify_observers_(spec.should_notify_observers) {} |
| 30 | 37 |
| 31 TaskQueueImpl::~TaskQueueImpl() {} | 38 TaskQueueImpl::~TaskQueueImpl() {} |
| 32 | 39 |
| 33 void TaskQueueImpl::WillDeleteTaskQueueManager() { | 40 void TaskQueueImpl::WillDeleteTaskQueueManager() { |
| 34 base::AutoLock lock(lock_); | 41 base::AutoLock lock(lock_); |
| 35 task_queue_manager_ = nullptr; | 42 task_queue_manager_ = nullptr; |
| 36 delayed_task_queue_ = base::DelayedTaskQueue(); | 43 delayed_task_queue_ = std::priority_queue<SchedulerTask>(); |
| 37 incoming_queue_ = base::TaskQueue(); | 44 incoming_queue_ = std::queue<SchedulerTask>(); |
| 38 work_queue_ = base::TaskQueue(); | 45 work_queue_ = std::queue<SchedulerTask>(); |
| 39 } | 46 } |
| 40 | 47 |
| 41 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { | 48 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { |
| 42 base::AutoLock lock(lock_); | 49 base::AutoLock lock(lock_); |
| 43 return base::PlatformThread::CurrentId() == thread_id_; | 50 return base::PlatformThread::CurrentId() == thread_id_; |
| 44 } | 51 } |
| 45 | 52 |
| 46 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, | 53 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, |
| 47 const base::Closure& task, | 54 const base::Closure& task, |
| 48 base::TimeDelta delay) { | 55 base::TimeDelta delay) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 | 93 |
| 87 bool TaskQueueImpl::PostDelayedTaskLocked( | 94 bool TaskQueueImpl::PostDelayedTaskLocked( |
| 88 LazyNow* lazy_now, | 95 LazyNow* lazy_now, |
| 89 const tracked_objects::Location& from_here, | 96 const tracked_objects::Location& from_here, |
| 90 const base::Closure& task, | 97 const base::Closure& task, |
| 91 base::TimeTicks desired_run_time, | 98 base::TimeTicks desired_run_time, |
| 92 TaskType task_type) { | 99 TaskType task_type) { |
| 93 lock_.AssertAcquired(); | 100 lock_.AssertAcquired(); |
| 94 DCHECK(task_queue_manager_); | 101 DCHECK(task_queue_manager_); |
| 95 | 102 |
| 96 base::PendingTask pending_task(from_here, task, base::TimeTicks(), | 103 SchedulerTask pending_task(from_here, task, |
| 97 task_type != TaskType::NON_NESTABLE); | 104 task_type != TaskType::NON_NESTABLE); |
| 98 task_queue_manager_->DidQueueTask(pending_task); | 105 task_queue_manager_->DidQueueTask(pending_task); |
| 99 | 106 |
| 100 if (!desired_run_time.is_null()) { | 107 if (!desired_run_time.is_null()) { |
| 101 pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); | 108 pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); |
| 102 pending_task.sequence_num = delayed_task_sequence_number_++; | 109 // TODO(alexclarke): consider emplace() when C++11 library features allowed. |
| 103 delayed_task_queue_.push(pending_task); | 110 delayed_task_queue_.push(pending_task); |
| 104 TraceQueueSize(true); | 111 TraceQueueSize(true); |
| 105 // If we changed the topmost task, then it is time to reschedule. | 112 // If we changed the topmost task, then it is time to reschedule. |
| 106 if (delayed_task_queue_.top().task.Equals(pending_task.task)) | 113 if (delayed_task_queue_.top().task.Equals(pending_task.task)) |
| 107 ScheduleDelayedWorkLocked(lazy_now); | 114 ScheduleDelayedWorkLocked(lazy_now); |
| 108 return true; | 115 return true; |
| 109 } | 116 } |
| 110 EnqueueTaskLocked(pending_task); | 117 EnqueueTaskLocked(pending_task); |
| 111 return true; | 118 return true; |
| 112 } | 119 } |
| 113 | 120 |
| 114 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue() { | 121 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue() { |
| 115 DCHECK(main_thread_checker_.CalledOnValidThread()); | 122 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 116 base::AutoLock lock(lock_); | 123 base::AutoLock lock(lock_); |
| 117 if (!task_queue_manager_) | 124 if (!task_queue_manager_) |
| 118 return; | 125 return; |
| 119 | 126 |
| 120 LazyNow lazy_now(task_queue_manager_); | 127 LazyNow lazy_now(task_queue_manager_); |
| 121 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); | 128 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); |
| 122 } | 129 } |
| 123 | 130 |
| 124 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( | 131 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( |
| 125 LazyNow* lazy_now) { | 132 LazyNow* lazy_now) { |
| 126 lock_.AssertAcquired(); | 133 lock_.AssertAcquired(); |
| 127 // Enqueue all delayed tasks that should be running now. | 134 // Enqueue all delayed tasks that should be running now. |
| 128 while (!delayed_task_queue_.empty() && | 135 while (!delayed_task_queue_.empty() && |
| 129 delayed_task_queue_.top().delayed_run_time <= lazy_now->Now()) { | 136 delayed_task_queue_.top().delayed_run_time <= lazy_now->Now()) { |
| 130 in_flight_kick_delayed_tasks_.erase( | 137 in_flight_kick_delayed_tasks_.erase( |
| 131 delayed_task_queue_.top().delayed_run_time); | 138 delayed_task_queue_.top().delayed_run_time); |
| 139 // TODO(alexclarke): consider std::move() when allowed. | |
| 132 EnqueueTaskLocked(delayed_task_queue_.top()); | 140 EnqueueTaskLocked(delayed_task_queue_.top()); |
| 133 delayed_task_queue_.pop(); | 141 delayed_task_queue_.pop(); |
| 134 } | 142 } |
| 135 TraceQueueSize(true); | 143 TraceQueueSize(true); |
| 136 ScheduleDelayedWorkLocked(lazy_now); | 144 ScheduleDelayedWorkLocked(lazy_now); |
| 137 } | 145 } |
| 138 | 146 |
| 139 void TaskQueueImpl::ScheduleDelayedWorkLocked(LazyNow* lazy_now) { | 147 void TaskQueueImpl::ScheduleDelayedWorkLocked(LazyNow* lazy_now) { |
| 140 lock_.AssertAcquired(); | 148 lock_.AssertAcquired(); |
| 141 // Any remaining tasks are in the future, so queue a task to kick them. | 149 // Any remaining tasks are in the future, so queue a task to kick them. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 { | 182 { |
| 175 base::AutoLock lock(lock_); | 183 base::AutoLock lock(lock_); |
| 176 if (incoming_queue_.empty()) { | 184 if (incoming_queue_.empty()) { |
| 177 return QueueState::EMPTY; | 185 return QueueState::EMPTY; |
| 178 } else { | 186 } else { |
| 179 return QueueState::NEEDS_PUMPING; | 187 return QueueState::NEEDS_PUMPING; |
| 180 } | 188 } |
| 181 } | 189 } |
| 182 } | 190 } |
| 183 | 191 |
| 184 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { | 192 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const SchedulerTask* task) { |
| 185 lock_.AssertAcquired(); | 193 lock_.AssertAcquired(); |
| 186 // A null task is passed when UpdateQueue is called before any task is run. | 194 // A null task is passed when UpdateQueue is called before any task is run. |
| 187 // In this case we don't want to pump an after_wakeup queue, so return true | 195 // In this case we don't want to pump an after_wakeup queue, so return true |
| 188 // here. | 196 // here. |
| 189 if (!task) | 197 if (!task) |
| 190 return true; | 198 return true; |
| 191 | 199 |
| 192 // Return false if there are no task in the incoming queue. | 200 // Return false if there are no task in the incoming queue. |
| 193 if (incoming_queue_.empty()) | 201 if (incoming_queue_.empty()) |
| 194 return false; | 202 return false; |
| 195 | 203 |
| 196 base::PendingTask oldest_queued_task = incoming_queue_.front(); | 204 const SchedulerTask& oldest_queued_task = incoming_queue_.front(); |
| 197 DCHECK(oldest_queued_task.delayed_run_time.is_null()); | 205 DCHECK(oldest_queued_task.delayed_run_time.is_null()); |
| 198 DCHECK(task->delayed_run_time.is_null()); | 206 DCHECK(task->delayed_run_time.is_null()); |
| 199 | 207 |
| 200 // Note: the comparison is correct due to the fact that the PendingTask | 208 // Note: the comparison is correct due to the fact that the SchedulerTask |
| 201 // operator inverts its comparison operation in order to work well in a heap | 209 // operator inverts its comparison operation in order to work well in a heap |
| 202 // based priority queue. | 210 // based priority queue. |
| 203 return oldest_queued_task < *task; | 211 return oldest_queued_task < *task; |
| 204 } | 212 } |
| 205 | 213 |
| 206 bool TaskQueueImpl::ShouldAutoPumpQueueLocked( | 214 bool TaskQueueImpl::ShouldAutoPumpQueueLocked( |
| 207 bool should_trigger_wakeup, | 215 bool should_trigger_wakeup, |
| 208 const base::PendingTask* previous_task) { | 216 const SchedulerTask* previous_task) { |
| 209 lock_.AssertAcquired(); | 217 lock_.AssertAcquired(); |
| 210 if (pump_policy_ == PumpPolicy::MANUAL) | 218 if (pump_policy_ == PumpPolicy::MANUAL) |
| 211 return false; | 219 return false; |
| 212 if (pump_policy_ == PumpPolicy::AFTER_WAKEUP && | 220 if (pump_policy_ == PumpPolicy::AFTER_WAKEUP && |
| 213 (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task))) | 221 (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task))) |
| 214 return false; | 222 return false; |
| 215 if (incoming_queue_.empty()) | 223 if (incoming_queue_.empty()) |
| 216 return false; | 224 return false; |
| 217 return true; | 225 return true; |
| 218 } | 226 } |
| 219 | 227 |
| 220 bool TaskQueueImpl::NextPendingDelayedTaskRunTime( | 228 bool TaskQueueImpl::NextPendingDelayedTaskRunTime( |
| 221 base::TimeTicks* next_pending_delayed_task) { | 229 base::TimeTicks* next_pending_delayed_task) { |
| 222 base::AutoLock lock(lock_); | 230 base::AutoLock lock(lock_); |
| 223 if (delayed_task_queue_.empty()) | 231 if (delayed_task_queue_.empty()) |
| 224 return false; | 232 return false; |
| 225 *next_pending_delayed_task = delayed_task_queue_.top().delayed_run_time; | 233 *next_pending_delayed_task = delayed_task_queue_.top().delayed_run_time; |
| 226 return true; | 234 return true; |
| 227 } | 235 } |
| 228 | 236 |
| 229 void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, | 237 void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, |
| 230 bool should_trigger_wakeup, | 238 bool should_trigger_wakeup, |
| 231 const base::PendingTask* previous_task) { | 239 const SchedulerTask* previous_task) { |
| 232 DCHECK(work_queue_.empty()); | 240 DCHECK(work_queue_.empty()); |
| 233 base::AutoLock lock(lock_); | 241 base::AutoLock lock(lock_); |
| 234 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) | 242 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) |
| 235 return; | 243 return; |
| 236 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); | 244 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); |
| 237 work_queue_.Swap(&incoming_queue_); | 245 std::swap(work_queue_, incoming_queue_); |
| 238 // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no | 246 // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no |
| 239 // longer needs to consider this queue for reloading. | 247 // longer needs to consider this queue for reloading. |
| 240 task_queue_manager_->UnregisterAsUpdatableTaskQueue(this); | 248 task_queue_manager_->UnregisterAsUpdatableTaskQueue(this); |
| 241 if (!work_queue_.empty()) { | 249 if (!work_queue_.empty()) { |
| 242 DCHECK(task_queue_manager_); | 250 DCHECK(task_queue_manager_); |
| 243 task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this); | 251 task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this); |
| 244 TraceQueueSize(true); | 252 TraceQueueSize(true); |
| 245 } | 253 } |
| 246 } | 254 } |
| 247 | 255 |
| 248 base::PendingTask TaskQueueImpl::TakeTaskFromWorkQueue() { | 256 SchedulerTask TaskQueueImpl::TakeTaskFromWorkQueue() { |
| 249 base::PendingTask pending_task = work_queue_.front(); | 257 // TODO(alexclarke): consider std::move() when allowed. |
| 258 SchedulerTask pending_task = work_queue_.front(); | |
| 250 work_queue_.pop(); | 259 work_queue_.pop(); |
| 251 DCHECK(task_queue_manager_); | 260 DCHECK(task_queue_manager_); |
| 252 task_queue_manager_->selector_.GetTaskQueueSets()->OnPopQueue(this); | 261 task_queue_manager_->selector_.GetTaskQueueSets()->OnPopQueue(this); |
| 253 TraceQueueSize(false); | 262 TraceQueueSize(false); |
| 254 return pending_task; | 263 return pending_task; |
| 255 } | 264 } |
| 256 | 265 |
| 257 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { | 266 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { |
| 258 bool is_tracing; | 267 bool is_tracing; |
| 259 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, | 268 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, |
| 260 &is_tracing); | 269 &is_tracing); |
| 261 if (!is_tracing) | 270 if (!is_tracing) |
| 262 return; | 271 return; |
| 263 if (!is_locked) | 272 if (!is_locked) |
| 264 lock_.Acquire(); | 273 lock_.Acquire(); |
| 265 else | 274 else |
| 266 lock_.AssertAcquired(); | 275 lock_.AssertAcquired(); |
| 267 TRACE_COUNTER1( | 276 TRACE_COUNTER1( |
| 268 disabled_by_default_tracing_category_, GetName(), | 277 disabled_by_default_tracing_category_, GetName(), |
| 269 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); | 278 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); |
| 270 if (!is_locked) | 279 if (!is_locked) |
| 271 lock_.Release(); | 280 lock_.Release(); |
| 272 } | 281 } |
| 273 | 282 |
| 274 void TaskQueueImpl::EnqueueTaskLocked(const base::PendingTask& pending_task) { | 283 void TaskQueueImpl::EnqueueTaskLocked(const SchedulerTask& pending_task) { |
| 275 lock_.AssertAcquired(); | 284 lock_.AssertAcquired(); |
| 276 if (!task_queue_manager_) | 285 if (!task_queue_manager_) |
| 277 return; | 286 return; |
| 278 if (incoming_queue_.empty()) | 287 if (incoming_queue_.empty()) |
| 279 task_queue_manager_->RegisterAsUpdatableTaskQueue(this); | 288 task_queue_manager_->RegisterAsUpdatableTaskQueue(this); |
| 280 if (pump_policy_ == PumpPolicy::AUTO && incoming_queue_.empty()) | 289 if (pump_policy_ == PumpPolicy::AUTO && incoming_queue_.empty()) |
| 281 task_queue_manager_->MaybePostDoWorkOnMainRunner(); | 290 task_queue_manager_->MaybePostDoWorkOnMainRunner(); |
| 291 // TODO(alexclarke): consider std::move() when allowed. | |
| 282 incoming_queue_.push(pending_task); | 292 incoming_queue_.push(pending_task); |
| 283 incoming_queue_.back().sequence_num = | 293 incoming_queue_.back().age = task_queue_manager_->GetNextAgeNumber(); |
|
Sami
2015/08/05 11:27:34
This means we're doing two atomic increments per P
| |
| 284 task_queue_manager_->GetNextSequenceNumber(); | |
| 285 | 294 |
| 286 if (!pending_task.delayed_run_time.is_null()) { | 295 if (!pending_task.delayed_run_time.is_null()) { |
| 287 // Clear the delayed run time because we've already applied the delay | 296 // Clear the delayed run time because we've already applied the delay |
| 288 // before getting here. | 297 // before getting here. |
| 289 incoming_queue_.back().delayed_run_time = base::TimeTicks(); | 298 incoming_queue_.back().delayed_run_time = base::TimeTicks(); |
| 290 } | 299 } |
| 291 TraceQueueSize(true); | 300 TraceQueueSize(true); |
| 292 } | 301 } |
| 293 | 302 |
| 294 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { | 303 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { |
| 295 base::AutoLock lock(lock_); | 304 base::AutoLock lock(lock_); |
| 296 if (pump_policy == PumpPolicy::AUTO && pump_policy_ != PumpPolicy::AUTO) { | 305 if (pump_policy == PumpPolicy::AUTO && pump_policy_ != PumpPolicy::AUTO) { |
| 297 PumpQueueLocked(); | 306 PumpQueueLocked(); |
| 298 } | 307 } |
| 299 pump_policy_ = pump_policy; | 308 pump_policy_ = pump_policy; |
| 300 } | 309 } |
| 301 | 310 |
| 302 void TaskQueueImpl::PumpQueueLocked() { | 311 void TaskQueueImpl::PumpQueueLocked() { |
| 303 lock_.AssertAcquired(); | 312 lock_.AssertAcquired(); |
| 304 if (!task_queue_manager_) | 313 if (!task_queue_manager_) |
| 305 return; | 314 return; |
| 306 | 315 |
| 307 LazyNow lazy_now(task_queue_manager_); | 316 LazyNow lazy_now(task_queue_manager_); |
| 308 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); | 317 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); |
| 309 | 318 |
| 310 bool was_empty = work_queue_.empty(); | 319 bool was_empty = work_queue_.empty(); |
| 311 while (!incoming_queue_.empty()) { | 320 while (!incoming_queue_.empty()) { |
| 321 // TODO(alexclarke): consider std::move() when allowed. | |
| 312 work_queue_.push(incoming_queue_.front()); | 322 work_queue_.push(incoming_queue_.front()); |
| 313 incoming_queue_.pop(); | 323 incoming_queue_.pop(); |
| 314 } | 324 } |
| 315 // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no longer | 325 // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no longer |
| 316 // needs to consider this queue for reloading. | 326 // needs to consider this queue for reloading. |
| 317 task_queue_manager_->UnregisterAsUpdatableTaskQueue(this); | 327 task_queue_manager_->UnregisterAsUpdatableTaskQueue(this); |
| 318 if (!work_queue_.empty()) { | 328 if (!work_queue_.empty()) { |
| 319 if (was_empty) | 329 if (was_empty) |
| 320 task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this); | 330 task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this); |
| 321 task_queue_manager_->MaybePostDoWorkOnMainRunner(); | 331 task_queue_manager_->MaybePostDoWorkOnMainRunner(); |
| 322 } | 332 } |
| 323 } | 333 } |
| 324 | 334 |
| 325 void TaskQueueImpl::PumpQueue() { | 335 void TaskQueueImpl::PumpQueue() { |
| 326 base::AutoLock lock(lock_); | 336 base::AutoLock lock(lock_); |
| 327 PumpQueueLocked(); | 337 PumpQueueLocked(); |
| 328 } | 338 } |
| 329 | 339 |
| 330 const char* TaskQueueImpl::GetName() const { | 340 const char* TaskQueueImpl::GetName() const { |
| 331 return name_; | 341 return name_; |
| 332 } | 342 } |
| 333 | 343 |
| 334 bool TaskQueueImpl::GetWorkQueueFrontTaskAge(int* age) const { | 344 bool TaskQueueImpl::GetWorkQueueFrontTaskAge(int* age) const { |
| 335 if (work_queue_.empty()) | 345 if (work_queue_.empty()) |
| 336 return false; | 346 return false; |
| 337 *age = work_queue_.front().sequence_num; | 347 *age = work_queue_.front().age; |
| 338 return true; | 348 return true; |
| 339 } | 349 } |
| 340 | 350 |
| 341 void TaskQueueImpl::PushTaskOntoWorkQueueForTest( | 351 void TaskQueueImpl::PushTaskOntoWorkQueueForTest(const SchedulerTask& task) { |
| 342 const base::PendingTask& task) { | |
| 343 work_queue_.push(task); | 352 work_queue_.push(task); |
| 344 } | 353 } |
| 345 | 354 |
| 346 void TaskQueueImpl::PopTaskFromWorkQueueForTest() { | 355 void TaskQueueImpl::PopTaskFromWorkQueueForTest() { |
| 347 work_queue_.pop(); | 356 work_queue_.pop(); |
| 348 } | 357 } |
| 349 | 358 |
| 350 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { | 359 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { |
| 351 DCHECK(main_thread_checker_.CalledOnValidThread()); | 360 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 352 if (!task_queue_manager_) | 361 if (!task_queue_manager_) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 state->BeginArray("delayed_task_queue"); | 435 state->BeginArray("delayed_task_queue"); |
| 427 QueueAsValueInto(delayed_task_queue_, state); | 436 QueueAsValueInto(delayed_task_queue_, state); |
| 428 state->EndArray(); | 437 state->EndArray(); |
| 429 } | 438 } |
| 430 state->SetString("priority", | 439 state->SetString("priority", |
| 431 PriorityToString(static_cast<QueuePriority>(set_index_))); | 440 PriorityToString(static_cast<QueuePriority>(set_index_))); |
| 432 state->EndDictionary(); | 441 state->EndDictionary(); |
| 433 } | 442 } |
| 434 | 443 |
| 435 // static | 444 // static |
| 436 void TaskQueueImpl::QueueAsValueInto(const base::TaskQueue& queue, | 445 void TaskQueueImpl::QueueAsValueInto(const std::queue<SchedulerTask>& queue, |
| 437 base::trace_event::TracedValue* state) { | 446 base::trace_event::TracedValue* state) { |
| 438 base::TaskQueue queue_copy(queue); | 447 std::queue<SchedulerTask> queue_copy(queue); |
| 439 while (!queue_copy.empty()) { | 448 while (!queue_copy.empty()) { |
| 440 TaskAsValueInto(queue_copy.front(), state); | 449 TaskAsValueInto(queue_copy.front(), state); |
| 441 queue_copy.pop(); | 450 queue_copy.pop(); |
| 442 } | 451 } |
| 443 } | 452 } |
| 444 | 453 |
| 445 // static | 454 // static |
| 446 void TaskQueueImpl::QueueAsValueInto(const base::DelayedTaskQueue& queue, | 455 void TaskQueueImpl::QueueAsValueInto( |
| 447 base::trace_event::TracedValue* state) { | 456 const std::priority_queue<SchedulerTask>& queue, |
| 448 base::DelayedTaskQueue queue_copy(queue); | 457 base::trace_event::TracedValue* state) { |
| 458 std::priority_queue<SchedulerTask> queue_copy(queue); | |
| 449 while (!queue_copy.empty()) { | 459 while (!queue_copy.empty()) { |
| 450 TaskAsValueInto(queue_copy.top(), state); | 460 TaskAsValueInto(queue_copy.top(), state); |
| 451 queue_copy.pop(); | 461 queue_copy.pop(); |
| 452 } | 462 } |
| 453 } | 463 } |
| 454 | 464 |
| 455 // static | 465 // static |
| 456 void TaskQueueImpl::TaskAsValueInto(const base::PendingTask& task, | 466 void TaskQueueImpl::TaskAsValueInto(const SchedulerTask& task, |
| 457 base::trace_event::TracedValue* state) { | 467 base::trace_event::TracedValue* state) { |
| 458 state->BeginDictionary(); | 468 state->BeginDictionary(); |
| 459 state->SetString("posted_from", task.posted_from.ToString()); | 469 state->SetString("posted_from", task.posted_from.ToString()); |
| 470 state->SetInteger("age", task.age); | |
| 460 state->SetInteger("sequence_num", task.sequence_num); | 471 state->SetInteger("sequence_num", task.sequence_num); |
| 461 state->SetBoolean("nestable", task.nestable); | 472 state->SetBoolean("nestable", task.nestable); |
| 462 state->SetBoolean("is_high_res", task.is_high_res); | 473 state->SetBoolean("is_high_res", task.is_high_res); |
| 463 state->SetDouble( | 474 state->SetDouble( |
| 464 "delayed_run_time", | 475 "delayed_run_time", |
| 465 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 476 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
| 466 state->EndDictionary(); | 477 state->EndDictionary(); |
| 467 } | 478 } |
| 468 | 479 |
| 469 } // namespace internal | 480 } // namespace internal |
| 470 } // namespace scheduler | 481 } // namespace scheduler |
| OLD | NEW |