Chromium Code Reviews| 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 "content/renderer/scheduler/task_queue_manager.h" | 5 #include "content/renderer/scheduler/task_queue_manager.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 ~TaskQueue() override; | 62 ~TaskQueue() override; |
| 63 | 63 |
| 64 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here, | 64 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here, |
| 65 const base::Closure& task, | 65 const base::Closure& task, |
| 66 base::TimeDelta delay, | 66 base::TimeDelta delay, |
| 67 bool nestable); | 67 bool nestable); |
| 68 | 68 |
| 69 void PumpQueueLocked(); | 69 void PumpQueueLocked(); |
| 70 void EnqueueTaskLocked(const base::PendingTask& pending_task); | 70 void EnqueueTaskLocked(const base::PendingTask& pending_task); |
| 71 | 71 |
| 72 void TraceWorkQueueSize() const; | 72 void TraceQueueSize(bool is_locked) const; |
| 73 static void QueueAsValueInto(const base::TaskQueue& queue, | 73 static void QueueAsValueInto(const base::TaskQueue& queue, |
| 74 base::trace_event::TracedValue* state); | 74 base::trace_event::TracedValue* state); |
| 75 static void TaskAsValueInto(const base::PendingTask& task, | 75 static void TaskAsValueInto(const base::PendingTask& task, |
| 76 base::trace_event::TracedValue* state); | 76 base::trace_event::TracedValue* state); |
| 77 | 77 |
| 78 // This lock protects all members except the work queue. | 78 // This lock protects all members except the work queue. |
| 79 mutable base::Lock lock_; | 79 mutable base::Lock lock_; |
| 80 TaskQueueManager* task_queue_manager_; | 80 TaskQueueManager* task_queue_manager_; |
| 81 base::TaskQueue incoming_queue_; | 81 base::TaskQueue incoming_queue_; |
| 82 bool auto_pump_; | 82 bool auto_pump_; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 | 148 |
| 149 { | 149 { |
| 150 base::AutoLock lock(lock_); | 150 base::AutoLock lock(lock_); |
| 151 if (!delayed_task_run_times_.empty()) { | 151 if (!delayed_task_run_times_.empty()) { |
| 152 *next_pending_delayed_task = | 152 *next_pending_delayed_task = |
| 153 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); | 153 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); |
| 154 } | 154 } |
| 155 if (!auto_pump_ || incoming_queue_.empty()) | 155 if (!auto_pump_ || incoming_queue_.empty()) |
| 156 return false; | 156 return false; |
| 157 work_queue_.Swap(&incoming_queue_); | 157 work_queue_.Swap(&incoming_queue_); |
| 158 TraceWorkQueueSize(); | 158 TraceQueueSize(true); |
| 159 return true; | 159 return true; |
| 160 } | 160 } |
| 161 } | 161 } |
| 162 | 162 |
| 163 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { | 163 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { |
| 164 base::PendingTask pending_task = work_queue_.front(); | 164 base::PendingTask pending_task = work_queue_.front(); |
| 165 work_queue_.pop(); | 165 work_queue_.pop(); |
| 166 TraceWorkQueueSize(); | 166 TraceQueueSize(false); |
| 167 return pending_task; | 167 return pending_task; |
| 168 } | 168 } |
| 169 | 169 |
| 170 void TaskQueue::TraceWorkQueueSize() const { | 170 void TaskQueue::TraceQueueSize(bool is_locked) const { |
| 171 if (!name_) | 171 bool is_tracing; |
| 172 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | |
| 173 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); | |
| 174 if (!is_tracing || !name_) | |
| 172 return; | 175 return; |
| 176 if (!is_locked) | |
|
alex clarke (OOO till 29th)
2015/02/25 12:37:51
Did you consider using lock_.Try() here?
alex clarke (OOO till 29th)
2015/02/25 12:38:51
Ah you can't do that on the same thread.
| |
| 177 lock_.Acquire(); | |
| 178 else | |
| 179 lock_.AssertAcquired(); | |
| 173 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, | 180 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, |
| 174 work_queue_.size()); | 181 incoming_queue_.size() + work_queue_.size()); |
| 182 if (!is_locked) | |
| 183 lock_.Release(); | |
| 175 } | 184 } |
| 176 | 185 |
| 177 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { | 186 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { |
| 178 base::AutoLock lock(lock_); | 187 base::AutoLock lock(lock_); |
| 179 EnqueueTaskLocked(pending_task); | 188 EnqueueTaskLocked(pending_task); |
| 180 } | 189 } |
| 181 | 190 |
| 182 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { | 191 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { |
| 183 lock_.AssertAcquired(); | 192 lock_.AssertAcquired(); |
| 184 if (!task_queue_manager_) | 193 if (!task_queue_manager_) |
| 185 return; | 194 return; |
| 186 if (auto_pump_ && incoming_queue_.empty()) | 195 if (auto_pump_ && incoming_queue_.empty()) |
| 187 task_queue_manager_->MaybePostDoWorkOnMainRunner(); | 196 task_queue_manager_->MaybePostDoWorkOnMainRunner(); |
| 188 incoming_queue_.push(pending_task); | 197 incoming_queue_.push(pending_task); |
| 189 | 198 |
| 190 if (!pending_task.delayed_run_time.is_null()) { | 199 if (!pending_task.delayed_run_time.is_null()) { |
| 191 // Update the time of the next pending delayed task. | 200 // Update the time of the next pending delayed task. |
| 192 while (!delayed_task_run_times_.empty() && | 201 while (!delayed_task_run_times_.empty() && |
| 193 delayed_task_run_times_.top() <= pending_task.delayed_run_time) { | 202 delayed_task_run_times_.top() <= pending_task.delayed_run_time) { |
| 194 delayed_task_run_times_.pop(); | 203 delayed_task_run_times_.pop(); |
| 195 } | 204 } |
| 196 // Clear the delayed run time because we've already applied the delay | 205 // Clear the delayed run time because we've already applied the delay |
| 197 // before getting here. | 206 // before getting here. |
| 198 incoming_queue_.back().delayed_run_time = base::TimeTicks(); | 207 incoming_queue_.back().delayed_run_time = base::TimeTicks(); |
| 199 } | 208 } |
| 209 TraceQueueSize(true); | |
| 200 } | 210 } |
| 201 | 211 |
| 202 void TaskQueue::SetAutoPump(bool auto_pump) { | 212 void TaskQueue::SetAutoPump(bool auto_pump) { |
| 203 base::AutoLock lock(lock_); | 213 base::AutoLock lock(lock_); |
| 204 if (auto_pump) { | 214 if (auto_pump) { |
| 205 auto_pump_ = true; | 215 auto_pump_ = true; |
| 206 PumpQueueLocked(); | 216 PumpQueueLocked(); |
| 207 } else { | 217 } else { |
| 208 auto_pump_ = false; | 218 auto_pump_ = false; |
| 209 } | 219 } |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 state->EndArray(); | 474 state->EndArray(); |
| 465 state->BeginDictionary("selector"); | 475 state->BeginDictionary("selector"); |
| 466 selector_->AsValueInto(state.get()); | 476 selector_->AsValueInto(state.get()); |
| 467 state->EndDictionary(); | 477 state->EndDictionary(); |
| 468 if (should_run) | 478 if (should_run) |
| 469 state->SetInteger("selected_queue", selected_queue); | 479 state->SetInteger("selected_queue", selected_queue); |
| 470 return state; | 480 return state; |
| 471 } | 481 } |
| 472 | 482 |
| 473 } // namespace content | 483 } // namespace content |
| OLD | NEW |