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

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

Issue 1690023005: Revert of Refactor signaling in RWP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « content/renderer/raster_worker_pool.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::SimpleThread {
23 public: 23 public:
24 RasterWorkerPoolThread(const std::string& name_prefix, 24 explicit RasterWorkerPoolThread(const std::string& name_prefix,
25 const Options& options, 25 const Options& options,
26 RasterWorkerPool* pool, 26 RasterWorkerPool* pool,
27 std::vector<cc::TaskCategory> categories, 27 std::vector<cc::TaskCategory> categories)
28 base::ConditionVariable* has_ready_to_run_tasks_cv)
29 : SimpleThread(name_prefix, options), 28 : SimpleThread(name_prefix, options),
30 pool_(pool), 29 pool_(pool),
31 categories_(categories), 30 categories_(categories) {}
32 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {}
33 31
34 void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } 32 void Run() override { pool_->Run(categories_); }
35 33
36 private: 34 private:
37 RasterWorkerPool* const pool_; 35 RasterWorkerPool* const pool_;
38 const std::vector<cc::TaskCategory> categories_; 36 const std::vector<cc::TaskCategory> categories_;
39 base::ConditionVariable* const has_ready_to_run_tasks_cv_;
40 }; 37 };
41 38
42 } // namespace 39 } // namespace
43 40
44 // A sequenced task runner which posts tasks to a RasterWorkerPool. 41 // A sequenced task runner which posts tasks to a RasterWorkerPool.
45 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner 42 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
46 : public base::SequencedTaskRunner { 43 : public base::SequencedTaskRunner {
47 public: 44 public:
48 explicit RasterWorkerPoolSequencedTaskRunner( 45 explicit RasterWorkerPoolSequencedTaskRunner(
49 cc::TaskGraphRunner* task_graph_runner) 46 cc::TaskGraphRunner* task_graph_runner)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 cc::Task::Vector tasks_; 109 cc::Task::Vector tasks_;
113 // Graph object used for scheduling tasks. 110 // Graph object used for scheduling tasks.
114 cc::TaskGraph graph_; 111 cc::TaskGraph graph_;
115 // Cached vector to avoid allocation when getting the list of complete 112 // Cached vector to avoid allocation when getting the list of complete
116 // tasks. 113 // tasks.
117 cc::Task::Vector completed_tasks_; 114 cc::Task::Vector completed_tasks_;
118 }; 115 };
119 116
120 RasterWorkerPool::RasterWorkerPool() 117 RasterWorkerPool::RasterWorkerPool()
121 : namespace_token_(GetNamespaceToken()), 118 : namespace_token_(GetNamespaceToken()),
122 has_ready_to_run_foreground_tasks_cv_(&lock_), 119 has_ready_to_run_tasks_cv_(&lock_),
123 has_ready_to_run_background_tasks_cv_(&lock_),
124 has_namespaces_with_finished_running_tasks_cv_(&lock_), 120 has_namespaces_with_finished_running_tasks_cv_(&lock_),
125 shutdown_(false) {} 121 shutdown_(false) {}
126 122
127 void RasterWorkerPool::Start( 123 void RasterWorkerPool::Start(
128 int num_threads, 124 int num_threads,
129 const base::SimpleThread::Options& thread_options) { 125 const base::SimpleThread::Options& thread_options) {
130 DCHECK(threads_.empty()); 126 DCHECK(threads_.empty());
127 while (threads_.size() < static_cast<size_t>(num_threads)) {
128 // Determine the categories that each thread can run.
129 std::vector<cc::TaskCategory> task_categories;
131 130
132 // Start |num_threads| threads for foreground work, including nonconcurrent 131 // The first thread can run nonconcurrent tasks.
133 // foreground work. 132 if (threads_.size() == 0) {
134 std::vector<cc::TaskCategory> foreground_categories; 133 task_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND);
135 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); 134 }
136 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND);
137 135
138 for (int i = 0; i < num_threads; i++) { 136 // All threads can run foreground tasks.
137 task_categories.push_back(cc::TASK_CATEGORY_FOREGROUND);
138
139 // The last thread can run background tasks.
140 if (threads_.size() == (static_cast<size_t>(num_threads) - 1)) {
141 task_categories.push_back(cc::TASK_CATEGORY_BACKGROUND);
142 }
143
139 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( 144 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
140 base::StringPrintf("CompositorTileWorker%u", 145 base::StringPrintf("CompositorTileWorker%u",
141 static_cast<unsigned>(threads_.size() + 1)) 146 static_cast<unsigned>(threads_.size() + 1))
142 .c_str(), 147 .c_str(),
143 thread_options, this, foreground_categories, 148 thread_options, this, task_categories));
144 &has_ready_to_run_foreground_tasks_cv_));
145 thread->Start(); 149 thread->Start();
146 threads_.push_back(std::move(thread)); 150 threads_.push_back(std::move(thread));
147 } 151 }
148
149 // Start a single thread for background work.
150 std::vector<cc::TaskCategory> background_categories;
151 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND);
152 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
153 base::StringPrintf("CompositorTileWorker%u",
154 static_cast<unsigned>(threads_.size() + 1))
155 .c_str(),
156 thread_options, this, background_categories,
157 &has_ready_to_run_background_tasks_cv_));
158 thread->Start();
159 threads_.push_back(std::move(thread));
160 } 152 }
161 153
162 void RasterWorkerPool::Shutdown() { 154 void RasterWorkerPool::Shutdown() {
163 WaitForTasksToFinishRunning(namespace_token_); 155 WaitForTasksToFinishRunning(namespace_token_);
164 CollectCompletedTasks(namespace_token_, &completed_tasks_); 156 CollectCompletedTasks(namespace_token_, &completed_tasks_);
165 // Shutdown raster threads. 157 // Shutdown raster threads.
166 { 158 {
167 base::AutoLock lock(lock_); 159 base::AutoLock lock(lock_);
168 160
169 DCHECK(!work_queue_.HasReadyToRunTasks()); 161 DCHECK(!work_queue_.HasReadyToRunTasks());
170 DCHECK(!work_queue_.HasAnyNamespaces()); 162 DCHECK(!work_queue_.HasAnyNamespaces());
171 163
172 DCHECK(!shutdown_); 164 DCHECK(!shutdown_);
173 shutdown_ = true; 165 shutdown_ = true;
174 166
175 // Wake up all workers so they exit. 167 // Wake up all workers so they exit.
176 has_ready_to_run_foreground_tasks_cv_.Broadcast(); 168 has_ready_to_run_tasks_cv_.Broadcast();
177 has_ready_to_run_background_tasks_cv_.Broadcast();
178 } 169 }
179 while (!threads_.empty()) { 170 while (!threads_.empty()) {
180 threads_.back()->Join(); 171 threads_.back()->Join();
181 threads_.pop_back(); 172 threads_.pop_back();
182 } 173 }
183 } 174 }
184 175
185 // Overridden from base::TaskRunner: 176 // Overridden from base::TaskRunner:
186 bool RasterWorkerPool::PostDelayedTask( 177 bool RasterWorkerPool::PostDelayedTask(
187 const tracked_objects::Location& from_here, 178 const tracked_objects::Location& from_here,
(...skipping 25 matching lines...) Expand all
213 204
214 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); 205 ScheduleTasksWithLockAcquired(namespace_token_, &graph_);
215 completed_tasks_.clear(); 206 completed_tasks_.clear();
216 return true; 207 return true;
217 } 208 }
218 209
219 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { 210 bool RasterWorkerPool::RunsTasksOnCurrentThread() const {
220 return true; 211 return true;
221 } 212 }
222 213
223 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, 214 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories) {
224 base::ConditionVariable* has_ready_to_run_tasks_cv) {
225 base::AutoLock lock(lock_); 215 base::AutoLock lock(lock_);
226 216
227 while (true) { 217 while (true) {
228 if (!RunTaskWithLockAcquired(categories)) { 218 if (!RunTaskWithLockAcquired(categories)) {
229 // We are no longer running tasks, which may allow another category to
230 // start running. Signal other worker threads.
231 SignalHasReadyToRunTasksWithLockAcquired();
232
233 // Exit when shutdown is set and no more tasks are pending. 219 // Exit when shutdown is set and no more tasks are pending.
234 if (shutdown_) 220 if (shutdown_)
235 break; 221 break;
236 222
237 // Wait for more tasks. 223 // Wait for more tasks.
238 has_ready_to_run_tasks_cv->Wait(); 224 has_ready_to_run_tasks_cv_.Wait();
239 continue; 225 continue;
240 } 226 }
241 } 227 }
242 } 228 }
243 229
244 void RasterWorkerPool::FlushForTesting() { 230 void RasterWorkerPool::FlushForTesting() {
245 base::AutoLock lock(lock_); 231 base::AutoLock lock(lock_);
246 232
247 while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) { 233 while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) {
248 has_namespaces_with_finished_running_tasks_cv_.Wait(); 234 has_namespaces_with_finished_running_tasks_cv_.Wait();
(...skipping 24 matching lines...) Expand all
273 } 259 }
274 260
275 void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token, 261 void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token,
276 cc::TaskGraph* graph) { 262 cc::TaskGraph* graph) {
277 DCHECK(token.IsValid()); 263 DCHECK(token.IsValid());
278 DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); 264 DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph));
279 DCHECK(!shutdown_); 265 DCHECK(!shutdown_);
280 266
281 work_queue_.ScheduleTasks(token, graph); 267 work_queue_.ScheduleTasks(token, graph);
282 268
283 // There may be more work available, so wake up another worker thread. 269 // If there is more work available, wake up the other worker threads.
284 SignalHasReadyToRunTasksWithLockAcquired(); 270 if (work_queue_.HasReadyToRunTasks())
271 has_ready_to_run_tasks_cv_.Broadcast();
285 } 272 }
286 273
287 void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) { 274 void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) {
288 TRACE_EVENT0("disabled-by-default-cc.debug", 275 TRACE_EVENT0("disabled-by-default-cc.debug",
289 "RasterWorkerPool::WaitForTasksToFinishRunning"); 276 "RasterWorkerPool::WaitForTasksToFinishRunning");
290 277
291 DCHECK(token.IsValid()); 278 DCHECK(token.IsValid());
292 279
293 { 280 {
294 base::AutoLock lock(lock_); 281 base::AutoLock lock(lock_);
295 base::ThreadRestrictions::ScopedAllowWait allow_wait; 282 base::ThreadRestrictions::ScopedAllowWait allow_wait;
296 283
297 auto* task_namespace = work_queue_.GetNamespaceForToken(token); 284 auto* task_namespace = work_queue_.GetNamespaceForToken(token);
298 285
299 if (!task_namespace) 286 if (!task_namespace)
300 return; 287 return;
301 288
302 while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) 289 while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace))
303 has_namespaces_with_finished_running_tasks_cv_.Wait(); 290 has_namespaces_with_finished_running_tasks_cv_.Wait();
304
305 // There may be other namespaces that have finished running tasks, so wake
306 // up another origin thread.
307 has_namespaces_with_finished_running_tasks_cv_.Signal();
308 } 291 }
309 } 292 }
310 293
311 void RasterWorkerPool::CollectCompletedTasks( 294 void RasterWorkerPool::CollectCompletedTasks(
312 cc::NamespaceToken token, 295 cc::NamespaceToken token,
313 cc::Task::Vector* completed_tasks) { 296 cc::Task::Vector* completed_tasks) {
314 TRACE_EVENT0("disabled-by-default-cc.debug", 297 TRACE_EVENT0("disabled-by-default-cc.debug",
315 "RasterWorkerPool::CollectCompletedTasks"); 298 "RasterWorkerPool::CollectCompletedTasks");
316 299
317 { 300 {
318 base::AutoLock lock(lock_); 301 base::AutoLock lock(lock_);
319 CollectCompletedTasksWithLockAcquired(token, completed_tasks); 302 CollectCompletedTasksWithLockAcquired(token, completed_tasks);
320 } 303 }
321 } 304 }
322 305
323 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( 306 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired(
324 cc::NamespaceToken token, 307 cc::NamespaceToken token,
325 cc::Task::Vector* completed_tasks) { 308 cc::Task::Vector* completed_tasks) {
326 DCHECK(token.IsValid()); 309 DCHECK(token.IsValid());
327 work_queue_.CollectCompletedTasks(token, completed_tasks); 310 work_queue_.CollectCompletedTasks(token, completed_tasks);
328 } 311 }
329 312
330 bool RasterWorkerPool::RunTaskWithLockAcquired( 313 bool RasterWorkerPool::RunTaskWithLockAcquired(
331 const std::vector<cc::TaskCategory>& categories) { 314 const std::vector<cc::TaskCategory>& categories) {
332 for (const auto& category : categories) { 315 for (const auto& category : categories) {
333 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { 316 if (work_queue_.HasReadyToRunTasksForCategory(category)) {
334 RunTaskInCategoryWithLockAcquired(category); 317 RunTaskInCategoryWithLockAcquired(category);
335 return true; 318 return true;
336 } 319 }
337 } 320 }
338 return false; 321 return false;
339 } 322 }
340 323
341 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( 324 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired(
342 cc::TaskCategory category) { 325 cc::TaskCategory category) {
343 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); 326 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask");
344 327
345 lock_.AssertAcquired(); 328 lock_.AssertAcquired();
346 329
347 auto prioritized_task = work_queue_.GetNextTaskToRun(category); 330 auto prioritized_task = work_queue_.GetNextTaskToRun(category);
348 cc::Task* task = prioritized_task.task; 331 cc::Task* task = prioritized_task.task;
349 332
350 // There may be more work available, so wake up another worker thread.
351 SignalHasReadyToRunTasksWithLockAcquired();
352
353 // Call WillRun() before releasing |lock_| and running task. 333 // Call WillRun() before releasing |lock_| and running task.
354 task->WillRun(); 334 task->WillRun();
355 335
356 { 336 {
357 base::AutoUnlock unlock(lock_); 337 base::AutoUnlock unlock(lock_);
358 338
359 task->RunOnWorkerThread(); 339 task->RunOnWorkerThread();
360 } 340 }
361 341
362 // This will mark task as finished running. 342 // This will mark task as finished running.
363 task->DidRun(); 343 task->DidRun();
364 344
365 work_queue_.CompleteTask(prioritized_task); 345 work_queue_.CompleteTask(prioritized_task);
366 346
347 // We may have just dequeued more tasks, wake up the other worker threads.
348 if (work_queue_.HasReadyToRunTasks())
349 has_ready_to_run_tasks_cv_.Broadcast();
350
367 // If namespace has finished running all tasks, wake up origin threads. 351 // If namespace has finished running all tasks, wake up origin threads.
368 if (work_queue_.HasFinishedRunningTasksInNamespace( 352 if (work_queue_.HasFinishedRunningTasksInNamespace(
369 prioritized_task.task_namespace)) 353 prioritized_task.task_namespace))
370 has_namespaces_with_finished_running_tasks_cv_.Signal(); 354 has_namespaces_with_finished_running_tasks_cv_.Broadcast();
371 }
372
373 bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired(
374 cc::TaskCategory category) {
375 lock_.AssertAcquired();
376
377 if (!work_queue_.HasReadyToRunTasksForCategory(category))
378 return false;
379
380 if (category == cc::TASK_CATEGORY_BACKGROUND) {
381 // Only run background tasks if there are no foreground tasks running or
382 // ready to run.
383 size_t num_running_foreground_tasks =
384 work_queue_.NumRunningTasksForCategory(
385 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) +
386 work_queue_.NumRunningTasksForCategory(cc::TASK_CATEGORY_FOREGROUND);
387 bool has_ready_to_run_foreground_tasks =
388 work_queue_.HasReadyToRunTasksForCategory(
389 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) ||
390 work_queue_.HasReadyToRunTasksForCategory(cc::TASK_CATEGORY_FOREGROUND);
391
392 if (num_running_foreground_tasks > 0 || has_ready_to_run_foreground_tasks)
393 return false;
394 }
395
396 // Enforce that only one nonconcurrent task runs at a time.
397 if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND &&
398 work_queue_.NumRunningTasksForCategory(
399 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) {
400 return false;
401 }
402
403 return true;
404 }
405
406 void RasterWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() {
407 lock_.AssertAcquired();
408
409 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_FOREGROUND) ||
410 ShouldRunTaskForCategoryWithLockAcquired(
411 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND)) {
412 has_ready_to_run_foreground_tasks_cv_.Signal();
413 }
414
415 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_BACKGROUND)) {
416 has_ready_to_run_background_tasks_cv_.Signal();
417 }
418 } 355 }
419 356
420 RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure) 357 RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure)
421 : closure_(closure) {} 358 : closure_(closure) {}
422 359
423 // Overridden from cc::Task: 360 // Overridden from cc::Task:
424 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { 361 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() {
425 closure_.Run(); 362 closure_.Run();
426 closure_.Reset(); 363 closure_.Reset();
427 } 364 }
428 365
429 RasterWorkerPool::ClosureTask::~ClosureTask() {} 366 RasterWorkerPool::ClosureTask::~ClosureTask() {}
430 367
431 } // namespace content 368 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/raster_worker_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698