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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // Adds a task at the end of the incoming task queue and schedules a call to | 70 // Adds a task at the end of the incoming task queue and schedules a call to |
71 // TaskQueueManager::DoWork() if the incoming queue was empty and automatic | 71 // TaskQueueManager::DoWork() if the incoming queue was empty and automatic |
72 // pumping is enabled. Can be called on an arbitrary thread. | 72 // pumping is enabled. Can be called on an arbitrary thread. |
73 void EnqueueTask(const base::PendingTask& pending_task); | 73 void EnqueueTask(const base::PendingTask& pending_task); |
74 | 74 |
75 void PumpQueueLocked(); | 75 void PumpQueueLocked(); |
76 bool ShouldAutoPumpQueueLocked( | 76 bool ShouldAutoPumpQueueLocked( |
77 TaskQueueManager::WorkQueueUpdateEventType event_type); | 77 TaskQueueManager::WorkQueueUpdateEventType event_type); |
78 void EnqueueTaskLocked(const base::PendingTask& pending_task); | 78 void EnqueueTaskLocked(const base::PendingTask& pending_task); |
79 | 79 |
80 void TraceWorkQueueSize() const; | 80 void TraceQueueSize(bool is_locked) const; |
81 static const char* PumpPolicyToString( | 81 static const char* PumpPolicyToString( |
82 TaskQueueManager::PumpPolicy pump_policy); | 82 TaskQueueManager::PumpPolicy pump_policy); |
83 static void QueueAsValueInto(const base::TaskQueue& queue, | 83 static void QueueAsValueInto(const base::TaskQueue& queue, |
84 base::trace_event::TracedValue* state); | 84 base::trace_event::TracedValue* state); |
85 static void TaskAsValueInto(const base::PendingTask& task, | 85 static void TaskAsValueInto(const base::PendingTask& task, |
86 base::trace_event::TracedValue* state); | 86 base::trace_event::TracedValue* state); |
87 | 87 |
88 // This lock protects all members except the work queue. | 88 // This lock protects all members except the work queue. |
89 mutable base::Lock lock_; | 89 mutable base::Lock lock_; |
90 TaskQueueManager* task_queue_manager_; | 90 TaskQueueManager* task_queue_manager_; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 174 |
175 { | 175 { |
176 base::AutoLock lock(lock_); | 176 base::AutoLock lock(lock_); |
177 if (!delayed_task_run_times_.empty()) { | 177 if (!delayed_task_run_times_.empty()) { |
178 *next_pending_delayed_task = | 178 *next_pending_delayed_task = |
179 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); | 179 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); |
180 } | 180 } |
181 if (!ShouldAutoPumpQueueLocked(event_type)) | 181 if (!ShouldAutoPumpQueueLocked(event_type)) |
182 return false; | 182 return false; |
183 work_queue_.Swap(&incoming_queue_); | 183 work_queue_.Swap(&incoming_queue_); |
184 TraceWorkQueueSize(); | 184 TraceQueueSize(true); |
185 return true; | 185 return true; |
186 } | 186 } |
187 } | 187 } |
188 | 188 |
189 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { | 189 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { |
190 base::PendingTask pending_task = work_queue_.front(); | 190 base::PendingTask pending_task = work_queue_.front(); |
191 work_queue_.pop(); | 191 work_queue_.pop(); |
192 TraceWorkQueueSize(); | 192 TraceQueueSize(false); |
193 return pending_task; | 193 return pending_task; |
194 } | 194 } |
195 | 195 |
196 void TaskQueue::TraceWorkQueueSize() const { | 196 void TaskQueue::TraceQueueSize(bool is_locked) const { |
197 if (!name_) | 197 bool is_tracing; |
| 198 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| 199 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); |
| 200 if (!is_tracing || !name_) |
198 return; | 201 return; |
| 202 if (!is_locked) |
| 203 lock_.Acquire(); |
| 204 else |
| 205 lock_.AssertAcquired(); |
199 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, | 206 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, |
200 work_queue_.size()); | 207 incoming_queue_.size() + work_queue_.size()); |
| 208 if (!is_locked) |
| 209 lock_.Release(); |
201 } | 210 } |
202 | 211 |
203 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { | 212 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { |
204 base::AutoLock lock(lock_); | 213 base::AutoLock lock(lock_); |
205 EnqueueTaskLocked(pending_task); | 214 EnqueueTaskLocked(pending_task); |
206 } | 215 } |
207 | 216 |
208 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { | 217 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { |
209 lock_.AssertAcquired(); | 218 lock_.AssertAcquired(); |
210 if (!task_queue_manager_) | 219 if (!task_queue_manager_) |
211 return; | 220 return; |
212 if (pump_policy_ == TaskQueueManager::AUTO_PUMP_POLICY && | 221 if (pump_policy_ == TaskQueueManager::AUTO_PUMP_POLICY && |
213 incoming_queue_.empty()) | 222 incoming_queue_.empty()) |
214 task_queue_manager_->MaybePostDoWorkOnMainRunner(); | 223 task_queue_manager_->MaybePostDoWorkOnMainRunner(); |
215 incoming_queue_.push(pending_task); | 224 incoming_queue_.push(pending_task); |
216 | 225 |
217 if (!pending_task.delayed_run_time.is_null()) { | 226 if (!pending_task.delayed_run_time.is_null()) { |
218 // Update the time of the next pending delayed task. | 227 // Update the time of the next pending delayed task. |
219 while (!delayed_task_run_times_.empty() && | 228 while (!delayed_task_run_times_.empty() && |
220 delayed_task_run_times_.top() <= pending_task.delayed_run_time) { | 229 delayed_task_run_times_.top() <= pending_task.delayed_run_time) { |
221 delayed_task_run_times_.pop(); | 230 delayed_task_run_times_.pop(); |
222 } | 231 } |
223 // Clear the delayed run time because we've already applied the delay | 232 // Clear the delayed run time because we've already applied the delay |
224 // before getting here. | 233 // before getting here. |
225 incoming_queue_.back().delayed_run_time = base::TimeTicks(); | 234 incoming_queue_.back().delayed_run_time = base::TimeTicks(); |
226 } | 235 } |
| 236 TraceQueueSize(true); |
227 } | 237 } |
228 | 238 |
229 void TaskQueue::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) { | 239 void TaskQueue::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) { |
230 base::AutoLock lock(lock_); | 240 base::AutoLock lock(lock_); |
231 if (pump_policy == TaskQueueManager::AUTO_PUMP_POLICY && | 241 if (pump_policy == TaskQueueManager::AUTO_PUMP_POLICY && |
232 pump_policy_ != TaskQueueManager::AUTO_PUMP_POLICY) { | 242 pump_policy_ != TaskQueueManager::AUTO_PUMP_POLICY) { |
233 PumpQueueLocked(); | 243 PumpQueueLocked(); |
234 } | 244 } |
235 pump_policy_ = pump_policy; | 245 pump_policy_ = pump_policy; |
236 } | 246 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 state->EndArray(); | 552 state->EndArray(); |
543 state->BeginDictionary("selector"); | 553 state->BeginDictionary("selector"); |
544 selector_->AsValueInto(state.get()); | 554 selector_->AsValueInto(state.get()); |
545 state->EndDictionary(); | 555 state->EndDictionary(); |
546 if (should_run) | 556 if (should_run) |
547 state->SetInteger("selected_queue", selected_queue); | 557 state->SetInteger("selected_queue", selected_queue); |
548 return state; | 558 return state; |
549 } | 559 } |
550 | 560 |
551 } // namespace content | 561 } // namespace content |
OLD | NEW |