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

Side by Side Diff: content/renderer/raster_worker_pool.cc

Issue 1739993004: content: Implement dynamic priorities for raster threads. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: preparing for checkin. Created 4 years, 9 months 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 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 "content/renderer/raster_worker_pool.h" 5 #include "content/renderer/raster_worker_pool.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
13 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
14 #include "cc/base/math_util.h" 14 #include "cc/base/math_util.h"
15 #include "cc/raster/task_category.h" 15 #include "cc/raster/task_category.h"
16 16
17 namespace content { 17 namespace content {
18 namespace { 18 namespace {
19 19
20 // A thread which forwards to RasterWorkerPool::Run with the runnable 20 // A thread which forwards to RasterWorkerPool::Run with the runnable
21 // categories. 21 // categories.
22 class RasterWorkerPoolThread : public base::SimpleThread { 22 class RasterWorkerPoolThread : public base::DynamicPriorityThread,
23 public cc::TaskWorker {
23 public: 24 public:
24 RasterWorkerPoolThread(const std::string& name_prefix, 25 RasterWorkerPoolThread(const DynamicPriorityThread::PrioritySet& priorities,
26 const std::string& name_prefix,
25 const Options& options, 27 const Options& options,
26 RasterWorkerPool* pool, 28 RasterWorkerPool* pool,
27 std::vector<cc::TaskCategory> categories, 29 std::vector<cc::TaskCategory> categories,
28 base::ConditionVariable* has_ready_to_run_tasks_cv) 30 base::ConditionVariable* has_ready_to_run_tasks_cv)
29 : SimpleThread(name_prefix, options), 31 : DynamicPriorityThread(priorities, name_prefix, options),
30 pool_(pool), 32 pool_(pool),
31 categories_(categories), 33 categories_(categories),
32 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} 34 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {}
33 35
34 void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } 36 // Overridden from cc::TaskWorker:
37 bool TaskSpeedup() override { Speedup(); }
38 bool TaskSlowdown() override { SlowDown(); }
39 bool TaskDone() override { RestoreDefaultPriority(); }
40
41 // Overridden from base::DynamicPriorityThread:
42 void Run() override {
43 pool_->Run(this, categories_, has_ready_to_run_tasks_cv_);
44 }
35 45
36 private: 46 private:
37 RasterWorkerPool* const pool_; 47 RasterWorkerPool* const pool_;
38 const std::vector<cc::TaskCategory> categories_; 48 const std::vector<cc::TaskCategory> categories_;
39 base::ConditionVariable* const has_ready_to_run_tasks_cv_; 49 base::ConditionVariable* const has_ready_to_run_tasks_cv_;
40 }; 50 };
41 51
42 } // namespace 52 } // namespace
43 53
54 void RasterWorkerPool::AdjustWorkerPriorityForTask(cc::Task* task,
55 uint16_t old_category,
56 uint16_t new_category) {
57 if (old_category == new_category)
58 return;
59
60 // TODO(prashant.n): Handle slowing down of tasks either by setting background
61 // priority for worker OR cancelling the task.
62 if (new_category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND ||
63 new_category == cc::TASK_CATEGORY_FOREGROUND) {
64 if (task->GetWorker()->TaskSpeedup()) {
65 // LOG(ERROR) << "\nPRAS:: [" << std::hex << runner << "] "
66 // << runner->GetPrioritySetForDebugging()
67 // << ". Runner speeded up ^^^^^^^^^";
68 }
69 }
70 }
71
44 // A sequenced task runner which posts tasks to a RasterWorkerPool. 72 // A sequenced task runner which posts tasks to a RasterWorkerPool.
45 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner 73 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
46 : public base::SequencedTaskRunner { 74 : public base::SequencedTaskRunner {
47 public: 75 public:
48 explicit RasterWorkerPoolSequencedTaskRunner( 76 explicit RasterWorkerPoolSequencedTaskRunner(
49 cc::TaskGraphRunner* task_graph_runner) 77 cc::TaskGraphRunner* task_graph_runner)
50 : task_graph_runner_(task_graph_runner), 78 : task_graph_runner_(task_graph_runner),
51 namespace_token_(task_graph_runner->GetNamespaceToken()) {} 79 namespace_token_(task_graph_runner->GetNamespaceToken()) {}
52 80
53 // Overridden from base::TaskRunner: 81 // Overridden from base::TaskRunner:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // List of tasks currently queued up for execution. 139 // List of tasks currently queued up for execution.
112 cc::Task::Vector tasks_; 140 cc::Task::Vector tasks_;
113 // Graph object used for scheduling tasks. 141 // Graph object used for scheduling tasks.
114 cc::TaskGraph graph_; 142 cc::TaskGraph graph_;
115 // Cached vector to avoid allocation when getting the list of complete 143 // Cached vector to avoid allocation when getting the list of complete
116 // tasks. 144 // tasks.
117 cc::Task::Vector completed_tasks_; 145 cc::Task::Vector completed_tasks_;
118 }; 146 };
119 147
120 RasterWorkerPool::RasterWorkerPool() 148 RasterWorkerPool::RasterWorkerPool()
121 : namespace_token_(GetNamespaceToken()), 149 : work_queue_(this),
150 namespace_token_(GetNamespaceToken()),
122 has_ready_to_run_foreground_tasks_cv_(&lock_), 151 has_ready_to_run_foreground_tasks_cv_(&lock_),
123 has_ready_to_run_background_tasks_cv_(&lock_), 152 has_ready_to_run_background_tasks_cv_(&lock_),
124 has_namespaces_with_finished_running_tasks_cv_(&lock_), 153 has_namespaces_with_finished_running_tasks_cv_(&lock_),
125 shutdown_(false) {} 154 shutdown_(false) {}
126 155
127 void RasterWorkerPool::Start(int num_threads) { 156 void RasterWorkerPool::Start(int num_threads) {
128 DCHECK(threads_.empty()); 157 DCHECK(threads_.empty());
129 158
130 // Start |num_threads| threads for foreground work, including nonconcurrent 159 // Start |num_threads| threads for foreground work, including nonconcurrent
131 // foreground work. 160 // foreground work.
132 std::vector<cc::TaskCategory> foreground_categories; 161 std::vector<cc::TaskCategory> foreground_categories;
133 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); 162 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND);
134 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); 163 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND);
135 164
165 base::DynamicPriorityThread::PrioritySet only_foreground(
166 base::ThreadPriority::NORMAL, base::ThreadPriority::NORMAL,
167 base::ThreadPriority::NORMAL);
168
169 base::DynamicPriorityThread::PrioritySet dynamic_background(
170 base::ThreadPriority::BACKGROUND, base::ThreadPriority::BACKGROUND,
171 base::ThreadPriority::NORMAL);
172
173 // Create N normal priority threads and 1 background priority dynamic thread.
136 for (int i = 0; i < num_threads; i++) { 174 for (int i = 0; i < num_threads; i++) {
137 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( 175 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
176 only_foreground,
138 base::StringPrintf("CompositorTileWorker%u", 177 base::StringPrintf("CompositorTileWorker%u",
139 static_cast<unsigned>(threads_.size() + 1)) 178 static_cast<unsigned>(threads_.size() + 1))
140 .c_str(), 179 .c_str(),
141 base::SimpleThread::Options(), this, foreground_categories, 180 base::SimpleThread::Options(), this, foreground_categories,
142 &has_ready_to_run_foreground_tasks_cv_)); 181 &has_ready_to_run_foreground_tasks_cv_));
143 thread->Start(); 182 thread->Start();
144 threads_.push_back(std::move(thread)); 183 threads_.push_back(std::move(thread));
145 } 184 }
146 185
147 // Start a single thread for background work. 186 // Start a single thread for background work.
148 std::vector<cc::TaskCategory> background_categories; 187 std::vector<cc::TaskCategory> background_categories;
149 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); 188 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND);
150 189
151 // Use background priority for background thread. 190 // Use background priority for background thread.
152 base::SimpleThread::Options thread_options; 191 base::SimpleThread::Options thread_options;
153 #if !defined(OS_MACOSX) 192 #if !defined(OS_MACOSX)
154 thread_options.set_priority(base::ThreadPriority::BACKGROUND); 193 thread_options.set_priority(base::ThreadPriority::BACKGROUND);
155 #endif 194 #endif
156 195
157 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( 196 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
197 dynamic_background,
158 base::StringPrintf("CompositorTileWorker%u", 198 base::StringPrintf("CompositorTileWorker%u",
159 static_cast<unsigned>(threads_.size() + 1)) 199 static_cast<unsigned>(threads_.size() + 1))
160 .c_str(), 200 .c_str(),
161 thread_options, this, background_categories, 201 thread_options, this, background_categories,
162 &has_ready_to_run_background_tasks_cv_)); 202 &has_ready_to_run_background_tasks_cv_));
163 thread->Start(); 203 thread->Start();
164 threads_.push_back(std::move(thread)); 204 threads_.push_back(std::move(thread));
165 } 205 }
166 206
167 void RasterWorkerPool::Shutdown() { 207 void RasterWorkerPool::Shutdown() {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 258
219 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); 259 ScheduleTasksWithLockAcquired(namespace_token_, &graph_);
220 completed_tasks_.clear(); 260 completed_tasks_.clear();
221 return true; 261 return true;
222 } 262 }
223 263
224 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { 264 bool RasterWorkerPool::RunsTasksOnCurrentThread() const {
225 return true; 265 return true;
226 } 266 }
227 267
228 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, 268 void RasterWorkerPool::Run(cc::TaskWorker* worker,
269 const std::vector<cc::TaskCategory>& categories,
229 base::ConditionVariable* has_ready_to_run_tasks_cv) { 270 base::ConditionVariable* has_ready_to_run_tasks_cv) {
230 base::AutoLock lock(lock_); 271 base::AutoLock lock(lock_);
231 272
232 while (true) { 273 while (true) {
233 if (!RunTaskWithLockAcquired(categories)) { 274 if (!RunTaskWithLockAcquired(worker, categories)) {
234 // We are no longer running tasks, which may allow another category to 275 // We are no longer running tasks, which may allow another category to
235 // start running. Signal other worker threads. 276 // start running. Signal other worker threads.
236 SignalHasReadyToRunTasksWithLockAcquired(); 277 SignalHasReadyToRunTasksWithLockAcquired();
237 278
238 // Exit when shutdown is set and no more tasks are pending. 279 // Exit when shutdown is set and no more tasks are pending.
239 if (shutdown_) 280 if (shutdown_)
240 break; 281 break;
241 282
242 // Wait for more tasks. 283 // Wait for more tasks.
243 has_ready_to_run_tasks_cv->Wait(); 284 has_ready_to_run_tasks_cv->Wait();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 // up another origin thread. 352 // up another origin thread.
312 has_namespaces_with_finished_running_tasks_cv_.Signal(); 353 has_namespaces_with_finished_running_tasks_cv_.Signal();
313 } 354 }
314 } 355 }
315 356
316 void RasterWorkerPool::CollectCompletedTasks( 357 void RasterWorkerPool::CollectCompletedTasks(
317 cc::NamespaceToken token, 358 cc::NamespaceToken token,
318 cc::Task::Vector* completed_tasks) { 359 cc::Task::Vector* completed_tasks) {
319 TRACE_EVENT0("disabled-by-default-cc.debug", 360 TRACE_EVENT0("disabled-by-default-cc.debug",
320 "RasterWorkerPool::CollectCompletedTasks"); 361 "RasterWorkerPool::CollectCompletedTasks");
321
322 { 362 {
323 base::AutoLock lock(lock_); 363 base::AutoLock lock(lock_);
324 CollectCompletedTasksWithLockAcquired(token, completed_tasks); 364 CollectCompletedTasksWithLockAcquired(token, completed_tasks);
325 } 365 }
326 } 366 }
327 367
328 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( 368 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired(
329 cc::NamespaceToken token, 369 cc::NamespaceToken token,
330 cc::Task::Vector* completed_tasks) { 370 cc::Task::Vector* completed_tasks) {
331 DCHECK(token.IsValid()); 371 DCHECK(token.IsValid());
332 work_queue_.CollectCompletedTasks(token, completed_tasks); 372 work_queue_.CollectCompletedTasks(token, completed_tasks);
333 } 373 }
334 374
335 bool RasterWorkerPool::RunTaskWithLockAcquired( 375 bool RasterWorkerPool::RunTaskWithLockAcquired(
376 cc::TaskWorker* worker,
336 const std::vector<cc::TaskCategory>& categories) { 377 const std::vector<cc::TaskCategory>& categories) {
337 for (const auto& category : categories) { 378 for (const auto& category : categories) {
338 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { 379 if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
339 RunTaskInCategoryWithLockAcquired(category); 380 RunTaskInCategoryWithLockAcquired(worker, category);
340 return true; 381 return true;
341 } 382 }
342 } 383 }
343 return false; 384 return false;
344 } 385 }
345 386
346 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( 387 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired(
388 cc::TaskWorker* worker,
347 cc::TaskCategory category) { 389 cc::TaskCategory category) {
348 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); 390 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask");
349 391
350 lock_.AssertAcquired(); 392 lock_.AssertAcquired();
351 393
352 auto prioritized_task = work_queue_.GetNextTaskToRun(category); 394 auto prioritized_task = work_queue_.GetNextTaskToRun(category);
353 cc::Task* task = prioritized_task.task; 395 cc::Task* task = prioritized_task.task;
354 396
397 // Attach the worker to the task.
398 AutoDetachTaskWorker task_worker(task, worker);
399
355 // There may be more work available, so wake up another worker thread. 400 // There may be more work available, so wake up another worker thread.
356 SignalHasReadyToRunTasksWithLockAcquired(); 401 SignalHasReadyToRunTasksWithLockAcquired();
357 402
358 // Call WillRun() before releasing |lock_| and running task. 403 // Call WillRun() before releasing |lock_| and running task.
359 task->WillRun(); 404 task->WillRun();
360 405
361 { 406 {
362 base::AutoUnlock unlock(lock_); 407 base::AutoUnlock unlock(lock_);
363 408
364 task->RunOnWorkerThread(); 409 task->RunOnWorkerThread();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 472
428 // Overridden from cc::Task: 473 // Overridden from cc::Task:
429 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { 474 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() {
430 closure_.Run(); 475 closure_.Run();
431 closure_.Reset(); 476 closure_.Reset();
432 } 477 }
433 478
434 RasterWorkerPool::ClosureTask::~ClosureTask() {} 479 RasterWorkerPool::ClosureTask::~ClosureTask() {}
435 480
436 } // namespace content 481 } // namespace content
OLDNEW
« cc/raster/task_graph_runner.cc ('K') | « content/renderer/raster_worker_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698