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

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: Removed unused function. 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);
54 void TraceWorkQueueSize() const;
49 55
50 // This lock protects all members except the work queue. 56 // This lock protects all members except the work queue.
51 mutable base::Lock lock_; 57 mutable base::Lock lock_;
52 TaskQueueManager* task_queue_manager_; 58 TaskQueueManager* task_queue_manager_;
53 base::TaskQueue incoming_queue_; 59 base::TaskQueue incoming_queue_;
54 bool auto_pump_; 60 bool auto_pump_;
61 const char* name_;
55 62
56 base::TaskQueue work_queue_; 63 base::TaskQueue work_queue_;
57 64
58 DISALLOW_COPY_AND_ASSIGN(TaskQueue); 65 DISALLOW_COPY_AND_ASSIGN(TaskQueue);
59 }; 66 };
60 67
61 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager) 68 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager)
62 : task_queue_manager_(task_queue_manager), auto_pump_(true) { 69 : task_queue_manager_(task_queue_manager),
70 auto_pump_(true),
71 name_(nullptr) {
63 } 72 }
64 73
65 TaskQueue::~TaskQueue() { 74 TaskQueue::~TaskQueue() {
66 } 75 }
67 76
68 void TaskQueue::WillDeleteTaskQueueManager() { 77 void TaskQueue::WillDeleteTaskQueueManager() {
69 base::AutoLock lock(lock_); 78 base::AutoLock lock(lock_);
70 task_queue_manager_ = nullptr; 79 task_queue_manager_ = nullptr;
71 } 80 }
72 81
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 127
119 bool TaskQueue::UpdateWorkQueue() { 128 bool TaskQueue::UpdateWorkQueue() {
120 if (!work_queue_.empty()) 129 if (!work_queue_.empty())
121 return true; 130 return true;
122 131
123 { 132 {
124 base::AutoLock lock(lock_); 133 base::AutoLock lock(lock_);
125 if (!auto_pump_ || incoming_queue_.empty()) 134 if (!auto_pump_ || incoming_queue_.empty())
126 return false; 135 return false;
127 work_queue_.Swap(&incoming_queue_); 136 work_queue_.Swap(&incoming_queue_);
137 TraceWorkQueueSize();
128 return true; 138 return true;
129 } 139 }
130 } 140 }
131 141
132 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { 142 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() {
133 base::PendingTask pending_task = work_queue_.front(); 143 base::PendingTask pending_task = work_queue_.front();
134 work_queue_.pop(); 144 work_queue_.pop();
145 TraceWorkQueueSize();
135 return pending_task; 146 return pending_task;
136 } 147 }
137 148
149 void TaskQueue::TraceWorkQueueSize() const {
150 if (!name_)
151 return;
152 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
153 name_,
154 work_queue_.size());
155 }
156
138 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) { 157 void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) {
139 base::AutoLock lock(lock_); 158 base::AutoLock lock(lock_);
140 EnqueueTaskLocked(pending_task); 159 EnqueueTaskLocked(pending_task);
141 } 160 }
142 161
143 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { 162 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) {
144 lock_.AssertAcquired(); 163 lock_.AssertAcquired();
145 if (!task_queue_manager_) 164 if (!task_queue_manager_)
146 return; 165 return;
147 if (auto_pump_ && incoming_queue_.empty()) 166 if (auto_pump_ && incoming_queue_.empty())
(...skipping 19 matching lines...) Expand all
167 } 186 }
168 if (!work_queue_.empty()) 187 if (!work_queue_.empty())
169 task_queue_manager_->PostDoWorkOnMainRunner(); 188 task_queue_manager_->PostDoWorkOnMainRunner();
170 } 189 }
171 190
172 void TaskQueue::PumpQueue() { 191 void TaskQueue::PumpQueue() {
173 base::AutoLock lock(lock_); 192 base::AutoLock lock(lock_);
174 PumpQueueLocked(); 193 PumpQueueLocked();
175 } 194 }
176 195
177 } // namespace 196 void TaskQueue::AsValueInto(base::debug::TracedValue* state) const {
197 base::AutoLock lock(lock_);
198 state->BeginDictionary();
199 if (name_)
200 state->SetString("name", name_);
201 state->SetBoolean("auto_pump", auto_pump_);
202 state->BeginArray("incoming_queue");
203 TaskQueueManager::QueueAsValueInto(incoming_queue_, state);
204 state->EndArray();
205 state->BeginArray("work_queue");
206 TaskQueueManager::QueueAsValueInto(work_queue_, state);
207 state->EndArray();
208 state->EndDictionary();
209 }
210
211 } // namespace internal
178 212
179 TaskQueueManager::TaskQueueManager( 213 TaskQueueManager::TaskQueueManager(
180 size_t task_queue_count, 214 size_t task_queue_count,
181 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 215 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
182 TaskQueueSelector* selector) 216 TaskQueueSelector* selector)
183 : main_task_runner_(main_task_runner), 217 : main_task_runner_(main_task_runner),
184 selector_(selector), 218 selector_(selector),
185 weak_factory_(this) { 219 weak_factory_(this) {
186 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); 220 DCHECK(main_task_runner->RunsTasksOnCurrentThread());
221 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
222 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
223 "TaskQueueManager",
224 this);
187 225
188 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); 226 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr();
189 for (size_t i = 0; i < task_queue_count; i++) { 227 for (size_t i = 0; i < task_queue_count; i++) {
190 scoped_refptr<internal::TaskQueue> queue( 228 scoped_refptr<internal::TaskQueue> queue(
191 make_scoped_refptr(new internal::TaskQueue(this))); 229 make_scoped_refptr(new internal::TaskQueue(this)));
192 queues_.push_back(queue); 230 queues_.push_back(queue);
193 } 231 }
194 232
195 std::vector<const base::TaskQueue*> work_queues; 233 std::vector<const base::TaskQueue*> work_queues;
196 for (const auto& queue: queues_) 234 for (const auto& queue: queues_)
197 work_queues.push_back(&queue->work_queue()); 235 work_queues.push_back(&queue->work_queue());
198 selector_->RegisterWorkQueues(work_queues); 236 selector_->RegisterWorkQueues(work_queues);
199 } 237 }
200 238
201 TaskQueueManager::~TaskQueueManager() { 239 TaskQueueManager::~TaskQueueManager() {
240 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
241 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
242 "TaskQueueManager",
243 this);
202 for (auto& queue : queues_) 244 for (auto& queue : queues_)
203 queue->WillDeleteTaskQueueManager(); 245 queue->WillDeleteTaskQueueManager();
204 } 246 }
205 247
206 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { 248 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const {
207 DCHECK_LT(queue_index, queues_.size()); 249 DCHECK_LT(queue_index, queues_.size());
208 return queues_[queue_index].get(); 250 return queues_[queue_index].get();
209 } 251 }
210 252
211 scoped_refptr<base::SingleThreadTaskRunner> 253 scoped_refptr<base::SingleThreadTaskRunner>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 main_task_runner_->PostTask( 287 main_task_runner_->PostTask(
246 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_)); 288 FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_));
247 } 289 }
248 290
249 void TaskQueueManager::DoWork() { 291 void TaskQueueManager::DoWork() {
250 main_thread_checker_.CalledOnValidThread(); 292 main_thread_checker_.CalledOnValidThread();
251 if (!UpdateWorkQueues()) 293 if (!UpdateWorkQueues())
252 return; 294 return;
253 295
254 size_t queue_index; 296 size_t queue_index;
255 if (!selector_->SelectWorkQueueToService(&queue_index)) 297 if (!SelectWorkQueueToService(&queue_index))
256 return; 298 return;
257 PostDoWorkOnMainRunner(); 299 PostDoWorkOnMainRunner();
258 RunTaskFromWorkQueue(queue_index); 300 RunTaskFromWorkQueue(queue_index);
259 } 301 }
260 302
303 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) {
304 bool should_run = selector_->SelectWorkQueueToService(out_queue_index);
305 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
306 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
307 "TaskQueueManager",
308 this,
309 AsValueWithSelectorResult(should_run, *out_queue_index));
310 return should_run;
311 }
312
261 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { 313 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) {
262 pending_task->sequence_num = task_sequence_num_.GetNext(); 314 pending_task->sequence_num = task_sequence_num_.GetNext();
263 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); 315 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task);
264 } 316 }
265 317
266 void TaskQueueManager::RunTaskFromWorkQueue(size_t queue_index) { 318 void TaskQueueManager::RunTaskFromWorkQueue(size_t queue_index) {
267 main_thread_checker_.CalledOnValidThread(); 319 main_thread_checker_.CalledOnValidThread();
268 internal::TaskQueue* queue = Queue(queue_index); 320 internal::TaskQueue* queue = Queue(queue_index);
269 base::PendingTask pending_task = queue->TakeTaskFromWorkQueue(); 321 base::PendingTask pending_task = queue->TakeTaskFromWorkQueue();
270 task_annotator_.RunTask( 322 task_annotator_.RunTask(
(...skipping 13 matching lines...) Expand all
284 } 336 }
285 337
286 bool TaskQueueManager::PostNonNestableDelayedTask( 338 bool TaskQueueManager::PostNonNestableDelayedTask(
287 const tracked_objects::Location& from_here, 339 const tracked_objects::Location& from_here,
288 const base::Closure& task, 340 const base::Closure& task,
289 base::TimeDelta delay) { 341 base::TimeDelta delay) {
290 // Defer non-nestable work to the main task runner. 342 // Defer non-nestable work to the main task runner.
291 return main_task_runner_->PostNonNestableDelayedTask(from_here, task, delay); 343 return main_task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
292 } 344 }
293 345
346 void TaskQueueManager::SetQueueName(size_t queue_index, const char* name) {
347 main_thread_checker_.CalledOnValidThread();
348 internal::TaskQueue* queue = Queue(queue_index);
349 queue->set_name(name);
350 }
351
352 scoped_refptr<base::debug::ConvertableToTraceFormat>
353 TaskQueueManager::AsValueWithSelectorResult(bool should_run,
354 size_t selected_queue) const {
355 main_thread_checker_.CalledOnValidThread();
356 scoped_refptr<base::debug::TracedValue> state =
357 new base::debug::TracedValue();
358 state->BeginArray("queues");
359 for (auto& queue : queues_)
360 queue->AsValueInto(state.get());
361 state->EndArray();
362 state->BeginDictionary("selector");
363 selector_->AsValueInto(state.get());
364 state->EndDictionary();
365 if (should_run)
366 state->SetInteger("selected_queue", selected_queue);
367 return state;
368 }
369
370 // static
371 void TaskQueueManager::QueueAsValueInto(const base::TaskQueue& queue,
372 base::debug::TracedValue* state) {
373 base::TaskQueue queue_copy(queue);
374 while (!queue_copy.empty()) {
375 TaskAsValueInto(queue_copy.front(), state);
376 queue_copy.pop();
377 }
378 }
379
380 // static
381 void TaskQueueManager::TaskAsValueInto(const base::PendingTask& task,
382 base::debug::TracedValue* state) {
383 state->BeginDictionary();
384 state->SetString("posted_from", task.posted_from.ToString());
385 state->SetInteger("sequence_num", task.sequence_num);
386 state->SetBoolean("nestable", task.nestable);
387 state->SetBoolean("is_high_res", task.is_high_res);
388 state->SetDouble(
389 "time_posted",
390 (task.time_posted - base::TimeTicks()).InMicroseconds() / 1000.0L);
391 state->SetDouble(
392 "delayed_run_time",
393 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
394 state->EndDictionary();
395 }
396
294 } // namespace content 397 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698