Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(472)

Side by Side Diff: content/renderer/scheduler/task_queue_manager.cc

Issue 681793003: scheduler: Add support for tracing scheduler state (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Small reorganization. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/debug/trace_event_argument.h"
9 #include "content/renderer/scheduler/task_queue_selector.h" 10 #include "content/renderer/scheduler/task_queue_selector.h"
10 11
11 namespace content { 12 namespace content {
12 namespace internal { 13 namespace internal {
13 14
14 class TaskQueue : public base::SingleThreadTaskRunner { 15 class TaskQueue : public base::SingleThreadTaskRunner {
15 public: 16 public:
16 TaskQueue(TaskQueueManager* task_queue_manager); 17 TaskQueue(TaskQueueManager* task_queue_manager);
17 18
18 // base::SingleThreadTaskRunner implementation. 19 // base::SingleThreadTaskRunner implementation.
(...skipping 15 matching lines...) Expand all
34 void SetAutoPump(bool auto_pump); 35 void SetAutoPump(bool auto_pump);
35 void PumpQueue(); 36 void PumpQueue();
36 37
37 bool UpdateWorkQueue(); 38 bool UpdateWorkQueue();
38 base::PendingTask TakeTaskFromWorkQueue(); 39 base::PendingTask TakeTaskFromWorkQueue();
39 40
40 void WillDeleteTaskQueueManager(); 41 void WillDeleteTaskQueueManager();
41 42
42 base::TaskQueue& work_queue() { return work_queue_; } 43 base::TaskQueue& work_queue() { return work_queue_; }
43 44
45 void set_name(const char* name) { name_ = name; }
46
47 void AsValueInto(base::debug::TracedValue* state) const;
48
44 private: 49 private:
45 ~TaskQueue() override; 50 ~TaskQueue() override;
46 51
47 void PumpQueueLocked(); 52 void PumpQueueLocked();
48 void EnqueueTaskLocked(const base::PendingTask& pending_task); 53 void EnqueueTaskLocked(const base::PendingTask& pending_task);
49 54
55 void TraceWorkQueueSize() const;
56 static void QueueAsValueInto(const base::TaskQueue& queue,
57 base::debug::TracedValue* state);
58 static void TaskAsValueInto(const base::PendingTask& task,
59 base::debug::TracedValue* state);
60
50 // This lock protects all members except the work queue. 61 // This lock protects all members except the work queue.
51 mutable base::Lock lock_; 62 mutable base::Lock lock_;
52 TaskQueueManager* task_queue_manager_; 63 TaskQueueManager* task_queue_manager_;
53 base::TaskQueue incoming_queue_; 64 base::TaskQueue incoming_queue_;
54 bool auto_pump_; 65 bool auto_pump_;
66 const char* name_;
55 67
56 base::TaskQueue work_queue_; 68 base::TaskQueue work_queue_;
57 69
58 DISALLOW_COPY_AND_ASSIGN(TaskQueue); 70 DISALLOW_COPY_AND_ASSIGN(TaskQueue);
59 }; 71 };
60 72
61 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager) 73 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager)
62 : task_queue_manager_(task_queue_manager), auto_pump_(true) { 74 : task_queue_manager_(task_queue_manager),
75 auto_pump_(true),
76 name_(nullptr) {
63 } 77 }
64 78
65 TaskQueue::~TaskQueue() { 79 TaskQueue::~TaskQueue() {
66 } 80 }
67 81
68 void TaskQueue::WillDeleteTaskQueueManager() { 82 void TaskQueue::WillDeleteTaskQueueManager() {
69 base::AutoLock lock(lock_); 83 base::AutoLock lock(lock_);
70 task_queue_manager_ = nullptr; 84 task_queue_manager_ = nullptr;
71 } 85 }
72 86
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 132
119 bool TaskQueue::UpdateWorkQueue() { 133 bool TaskQueue::UpdateWorkQueue() {
120 if (!work_queue_.empty()) 134 if (!work_queue_.empty())
121 return true; 135 return true;
122 136
123 { 137 {
124 base::AutoLock lock(lock_); 138 base::AutoLock lock(lock_);
125 if (!auto_pump_ || incoming_queue_.empty()) 139 if (!auto_pump_ || incoming_queue_.empty())
126 return false; 140 return false;
127 work_queue_.Swap(&incoming_queue_); 141 work_queue_.Swap(&incoming_queue_);
142 TraceWorkQueueSize();
128 return true; 143 return true;
129 } 144 }
130 } 145 }
131 146
132 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { 147 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() {
133 base::PendingTask pending_task = work_queue_.front(); 148 base::PendingTask pending_task = work_queue_.front();
134 work_queue_.pop(); 149 work_queue_.pop();
150 TraceWorkQueueSize();
135 return pending_task; 151 return pending_task;
136 } 152 }
137 153
154 void TaskQueue::TraceWorkQueueSize() const {
155 if (!name_)
156 return;
157 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_,
158 work_queue_.size());
159 }
160
138 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { 161 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) {
139 base::AutoLock lock(lock_); 162 base::AutoLock lock(lock_);
140 EnqueueTaskLocked(pending_task); 163 EnqueueTaskLocked(pending_task);
141 } 164 }
142 165
143 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { 166 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) {
144 lock_.AssertAcquired(); 167 lock_.AssertAcquired();
145 if (!task_queue_manager_) 168 if (!task_queue_manager_)
146 return; 169 return;
147 if (auto_pump_ && incoming_queue_.empty()) 170 if (auto_pump_ && incoming_queue_.empty())
(...skipping 19 matching lines...) Expand all
167 } 190 }
168 if (!work_queue_.empty()) 191 if (!work_queue_.empty())
169 task_queue_manager_->PostDoWorkOnMainRunner(); 192 task_queue_manager_->PostDoWorkOnMainRunner();
170 } 193 }
171 194
172 void TaskQueue::PumpQueue() { 195 void TaskQueue::PumpQueue() {
173 base::AutoLock lock(lock_); 196 base::AutoLock lock(lock_);
174 PumpQueueLocked(); 197 PumpQueueLocked();
175 } 198 }
176 199
177 } // namespace 200 void TaskQueue::AsValueInto(base::debug::TracedValue* state) const {
201 base::AutoLock lock(lock_);
202 state->BeginDictionary();
203 if (name_)
204 state->SetString("name", name_);
205 state->SetBoolean("auto_pump", auto_pump_);
206 state->BeginArray("incoming_queue");
207 QueueAsValueInto(incoming_queue_, state);
208 state->EndArray();
209 state->BeginArray("work_queue");
210 QueueAsValueInto(work_queue_, state);
211 state->EndArray();
212 state->EndDictionary();
213 }
214
215 // static
216 void TaskQueue::QueueAsValueInto(const base::TaskQueue& queue,
217 base::debug::TracedValue* state) {
218 base::TaskQueue queue_copy(queue);
219 while (!queue_copy.empty()) {
220 TaskAsValueInto(queue_copy.front(), state);
221 queue_copy.pop();
222 }
223 }
224
225 // static
226 void TaskQueue::TaskAsValueInto(const base::PendingTask& task,
227 base::debug::TracedValue* state) {
228 state->BeginDictionary();
229 state->SetString("posted_from", task.posted_from.ToString());
230 state->SetInteger("sequence_num", task.sequence_num);
231 state->SetBoolean("nestable", task.nestable);
232 state->SetBoolean("is_high_res", task.is_high_res);
233 state->SetDouble(
234 "time_posted",
235 (task.time_posted - base::TimeTicks()).InMicroseconds() / 1000.0L);
236 state->SetDouble(
237 "delayed_run_time",
238 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
239 state->EndDictionary();
240 }
241
242 } // namespace internal
178 243
179 TaskQueueManager::TaskQueueManager( 244 TaskQueueManager::TaskQueueManager(
180 size_t task_queue_count, 245 size_t task_queue_count,
181 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 246 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
182 TaskQueueSelector* selector) 247 TaskQueueSelector* selector)
183 : main_task_runner_(main_task_runner), 248 : main_task_runner_(main_task_runner),
184 selector_(selector), 249 selector_(selector),
185 weak_factory_(this) { 250 weak_factory_(this) {
186 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); 251 DCHECK(main_task_runner->RunsTasksOnCurrentThread());
252 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
253 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager",
254 this);
187 255
188 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); 256 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr();
189 for (size_t i = 0; i < task_queue_count; i++) { 257 for (size_t i = 0; i < task_queue_count; i++) {
190 scoped_refptr<internal::TaskQueue> queue( 258 scoped_refptr<internal::TaskQueue> queue(
191 make_scoped_refptr(new internal::TaskQueue(this))); 259 make_scoped_refptr(new internal::TaskQueue(this)));
192 queues_.push_back(queue); 260 queues_.push_back(queue);
193 } 261 }
194 262
195 std::vector<const base::TaskQueue*> work_queues; 263 std::vector<const base::TaskQueue*> work_queues;
196 for (const auto& queue: queues_) 264 for (const auto& queue: queues_)
197 work_queues.push_back(&queue->work_queue()); 265 work_queues.push_back(&queue->work_queue());
198 selector_->RegisterWorkQueues(work_queues); 266 selector_->RegisterWorkQueues(work_queues);
199 } 267 }
200 268
201 TaskQueueManager::~TaskQueueManager() { 269 TaskQueueManager::~TaskQueueManager() {
270 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
271 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager",
272 this);
202 for (auto& queue : queues_) 273 for (auto& queue : queues_)
203 queue->WillDeleteTaskQueueManager(); 274 queue->WillDeleteTaskQueueManager();
204 } 275 }
205 276
206 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { 277 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const {
207 DCHECK_LT(queue_index, queues_.size()); 278 DCHECK_LT(queue_index, queues_.size());
208 return queues_[queue_index].get(); 279 return queues_[queue_index].get();
209 } 280 }
210 281
211 scoped_refptr<base::SingleThreadTaskRunner> 282 scoped_refptr<base::SingleThreadTaskRunner>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 main_task_runner_->PostTask( 316 main_task_runner_->PostTask(
246 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_)); 317 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_));
247 } 318 }
248 319
249 void TaskQueueManager::DoWork() { 320 void TaskQueueManager::DoWork() {
250 main_thread_checker_.CalledOnValidThread(); 321 main_thread_checker_.CalledOnValidThread();
251 if (!UpdateWorkQueues()) 322 if (!UpdateWorkQueues())
252 return; 323 return;
253 324
254 size_t queue_index; 325 size_t queue_index;
255 if (!selector_->SelectWorkQueueToService(&queue_index)) 326 if (!SelectWorkQueueToService(&queue_index))
256 return; 327 return;
257 PostDoWorkOnMainRunner(); 328 PostDoWorkOnMainRunner();
258 RunTaskFromWorkQueue(queue_index); 329 RunTaskFromWorkQueue(queue_index);
259 } 330 }
260 331
332 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) {
333 bool should_run = selector_->SelectWorkQueueToService(out_queue_index);
334 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
335 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", this,
336 AsValueWithSelectorResult(should_run, *out_queue_index));
337 return should_run;
338 }
339
261 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { 340 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) {
262 pending_task->sequence_num = task_sequence_num_.GetNext(); 341 pending_task->sequence_num = task_sequence_num_.GetNext();
263 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); 342 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task);
264 } 343 }
265 344
266 void TaskQueueManager::RunTaskFromWorkQueue(size_t queue_index) { 345 void TaskQueueManager::RunTaskFromWorkQueue(size_t queue_index) {
267 main_thread_checker_.CalledOnValidThread(); 346 main_thread_checker_.CalledOnValidThread();
268 internal::TaskQueue* queue = Queue(queue_index); 347 internal::TaskQueue* queue = Queue(queue_index);
269 base::PendingTask pending_task = queue->TakeTaskFromWorkQueue(); 348 base::PendingTask pending_task = queue->TakeTaskFromWorkQueue();
270 task_annotator_.RunTask( 349 task_annotator_.RunTask(
(...skipping 13 matching lines...) Expand all
284 } 363 }
285 364
286 bool TaskQueueManager::PostNonNestableDelayedTask( 365 bool TaskQueueManager::PostNonNestableDelayedTask(
287 const tracked_objects::Location& from_here, 366 const tracked_objects::Location& from_here,
288 const base::Closure& task, 367 const base::Closure& task,
289 base::TimeDelta delay) { 368 base::TimeDelta delay) {
290 // Defer non-nestable work to the main task runner. 369 // Defer non-nestable work to the main task runner.
291 return main_task_runner_->PostNonNestableDelayedTask(from_here, task, delay); 370 return main_task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
292 } 371 }
293 372
373 void TaskQueueManager::SetQueueName(size_t queue_index, const char* name) {
374 main_thread_checker_.CalledOnValidThread();
375 internal::TaskQueue* queue = Queue(queue_index);
376 queue->set_name(name);
377 }
378
379 scoped_refptr<base::debug::ConvertableToTraceFormat>
380 TaskQueueManager::AsValueWithSelectorResult(bool should_run,
381 size_t selected_queue) const {
382 main_thread_checker_.CalledOnValidThread();
383 scoped_refptr<base::debug::TracedValue> state =
384 new base::debug::TracedValue();
385 state->BeginArray("queues");
386 for (auto& queue : queues_)
387 queue->AsValueInto(state.get());
388 state->EndArray();
389 state->BeginDictionary("selector");
390 selector_->AsValueInto(state.get());
391 state->EndDictionary();
392 if (should_run)
393 state->SetInteger("selected_queue", selected_queue);
394 return state;
395 }
396
294 } // namespace content 397 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698