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

Side by Side Diff: cc/resources/worker_pool.cc

Issue 17351017: Re-land: cc: Add raster finished signals to RasterWorkerPool. (Closed) Base URL: http://git.chromium.org/chromium/src.git@new-graph-build
Patch Set: fix flaky unit tests Created 7 years, 5 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 | « cc/resources/worker_pool.h ('k') | cc/resources/worker_pool_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "cc/resources/worker_pool.h" 5 #include "cc/resources/worker_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <queue> 8 #include <queue>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 } 57 }
58 58
59 bool WorkerPoolTask::HasFinishedRunning() const { 59 bool WorkerPoolTask::HasFinishedRunning() const {
60 return did_run_; 60 return did_run_;
61 } 61 }
62 62
63 bool WorkerPoolTask::HasCompleted() const { 63 bool WorkerPoolTask::HasCompleted() const {
64 return did_complete_; 64 return did_complete_;
65 } 65 }
66 66
67 GraphNode::GraphNode(internal::WorkerPoolTask* task, unsigned priority)
68 : task_(task),
69 priority_(priority),
70 num_dependencies_(0) {
71 }
72
73 GraphNode::~GraphNode() {
74 }
75
67 } // namespace internal 76 } // namespace internal
68 77
69 // Internal to the worker pool. Any data or logic that needs to be 78 // Internal to the worker pool. Any data or logic that needs to be
70 // shared between threads lives in this class. All members are guarded 79 // shared between threads lives in this class. All members are guarded
71 // by |lock_|. 80 // by |lock_|.
72 class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate { 81 class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
73 public: 82 public:
74 Inner(size_t num_threads, const std::string& thread_name_prefix); 83 Inner(size_t num_threads, const std::string& thread_name_prefix);
75 virtual ~Inner(); 84 virtual ~Inner();
76 85
77 void Shutdown(); 86 void Shutdown();
78 87
79 // Schedule running of tasks in |graph|. Tasks previously scheduled but 88 // Schedule running of tasks in |graph|. Tasks previously scheduled but
80 // no longer needed will be canceled unless already running. Canceled 89 // no longer needed will be canceled unless already running. Canceled
81 // tasks are moved to |completed_tasks_| without being run. The result 90 // tasks are moved to |completed_tasks_| without being run. The result
82 // is that once scheduled, a task is guaranteed to end up in the 91 // is that once scheduled, a task is guaranteed to end up in the
83 // |completed_tasks_| queue even if they later get canceled by another 92 // |completed_tasks_| queue even if they later get canceled by another
84 // call to SetTaskGraph(). 93 // call to SetTaskGraph().
85 void SetTaskGraph(TaskGraph* graph); 94 void SetTaskGraph(TaskGraph* graph);
86 95
87 // Collect all completed tasks in |completed_tasks|. 96 // Collect all completed tasks in |completed_tasks|.
88 void CollectCompletedTasks(TaskVector* completed_tasks); 97 void CollectCompletedTasks(TaskVector* completed_tasks);
89 98
90 private: 99 private:
91 class PriorityComparator { 100 class PriorityComparator {
92 public: 101 public:
93 bool operator()(const GraphNode* a, 102 bool operator()(const internal::GraphNode* a,
94 const GraphNode* b) { 103 const internal::GraphNode* b) {
95 // In this system, numerically lower priority is run first. 104 // In this system, numerically lower priority is run first.
96 if (a->priority() != b->priority()) 105 if (a->priority() != b->priority())
97 return a->priority() > b->priority(); 106 return a->priority() > b->priority();
98 107
99 // Run task with most dependents first when priority is the same. 108 // Run task with most dependents first when priority is the same.
100 return a->dependents().size() < b->dependents().size(); 109 return a->dependents().size() < b->dependents().size();
101 } 110 }
102 }; 111 };
103 112
104 // Overridden from base::DelegateSimpleThread: 113 // Overridden from base::DelegateSimpleThread:
(...skipping 13 matching lines...) Expand all
118 unsigned next_thread_index_; 127 unsigned next_thread_index_;
119 128
120 // Set during shutdown. Tells workers to exit when no more tasks 129 // Set during shutdown. Tells workers to exit when no more tasks
121 // are pending. 130 // are pending.
122 bool shutdown_; 131 bool shutdown_;
123 132
124 // This set contains all pending tasks. 133 // This set contains all pending tasks.
125 GraphNodeMap pending_tasks_; 134 GraphNodeMap pending_tasks_;
126 135
127 // Ordered set of tasks that are ready to run. 136 // Ordered set of tasks that are ready to run.
128 typedef std::priority_queue<GraphNode*, 137 typedef std::priority_queue<internal::GraphNode*,
129 std::vector<GraphNode*>, 138 std::vector<internal::GraphNode*>,
130 PriorityComparator> TaskQueue; 139 PriorityComparator> TaskQueue;
131 TaskQueue ready_to_run_tasks_; 140 TaskQueue ready_to_run_tasks_;
132 141
133 // This set contains all currently running tasks. 142 // This set contains all currently running tasks.
134 GraphNodeMap running_tasks_; 143 GraphNodeMap running_tasks_;
135 144
136 // Completed tasks not yet collected by origin thread. 145 // Completed tasks not yet collected by origin thread.
137 TaskVector completed_tasks_; 146 TaskVector completed_tasks_;
138 147
139 ScopedPtrDeque<base::DelegateSimpleThread> workers_; 148 ScopedPtrDeque<base::DelegateSimpleThread> workers_;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 218
210 { 219 {
211 base::AutoLock lock(lock_); 220 base::AutoLock lock(lock_);
212 221
213 // First remove all completed tasks from |new_pending_tasks| and 222 // First remove all completed tasks from |new_pending_tasks| and
214 // adjust number of dependencies. 223 // adjust number of dependencies.
215 for (TaskVector::iterator it = completed_tasks_.begin(); 224 for (TaskVector::iterator it = completed_tasks_.begin();
216 it != completed_tasks_.end(); ++it) { 225 it != completed_tasks_.end(); ++it) {
217 internal::WorkerPoolTask* task = it->get(); 226 internal::WorkerPoolTask* task = it->get();
218 227
219 scoped_ptr<GraphNode> node = new_pending_tasks.take_and_erase(task); 228 scoped_ptr<internal::GraphNode> node = new_pending_tasks.take_and_erase(
229 task);
220 if (node) { 230 if (node) {
221 for (GraphNode::Vector::const_iterator it = node->dependents().begin(); 231 for (internal::GraphNode::Vector::const_iterator it =
232 node->dependents().begin();
222 it != node->dependents().end(); ++it) { 233 it != node->dependents().end(); ++it) {
223 GraphNode* dependent_node = *it; 234 internal::GraphNode* dependent_node = *it;
224 dependent_node->remove_dependency(); 235 dependent_node->remove_dependency();
225 } 236 }
226 } 237 }
227 } 238 }
228 239
229 // Build new running task set. 240 // Build new running task set.
230 for (GraphNodeMap::iterator it = running_tasks_.begin(); 241 for (GraphNodeMap::iterator it = running_tasks_.begin();
231 it != running_tasks_.end(); ++it) { 242 it != running_tasks_.end(); ++it) {
232 internal::WorkerPoolTask* task = it->first; 243 internal::WorkerPoolTask* task = it->first;
233 // Transfer scheduled task value from |new_pending_tasks| to 244 // Transfer scheduled task value from |new_pending_tasks| to
234 // |new_running_tasks| if currently running. Value must be set to 245 // |new_running_tasks| if currently running. Value must be set to
235 // NULL if |new_pending_tasks| doesn't contain task. This does 246 // NULL if |new_pending_tasks| doesn't contain task. This does
236 // the right in both cases. 247 // the right in both cases.
237 new_running_tasks.set(task, new_pending_tasks.take_and_erase(task)); 248 new_running_tasks.set(task, new_pending_tasks.take_and_erase(task));
238 } 249 }
239 250
240 // Build new "ready to run" tasks queue. 251 // Build new "ready to run" tasks queue.
241 // TODO(reveman): Create this queue when building the task graph instead. 252 // TODO(reveman): Create this queue when building the task graph instead.
242 for (GraphNodeMap::iterator it = new_pending_tasks.begin(); 253 for (GraphNodeMap::iterator it = new_pending_tasks.begin();
243 it != new_pending_tasks.end(); ++it) { 254 it != new_pending_tasks.end(); ++it) {
244 internal::WorkerPoolTask* task = it->first; 255 internal::WorkerPoolTask* task = it->first;
245 DCHECK(task); 256 DCHECK(task);
246 GraphNode* node = it->second; 257 internal::GraphNode* node = it->second;
247 258
248 // Completed tasks should not exist in |new_pending_tasks|. 259 // Completed tasks should not exist in |new_pending_tasks|.
249 DCHECK(!task->HasFinishedRunning()); 260 DCHECK(!task->HasFinishedRunning());
250 261
251 // Call DidSchedule() to indicate that this task has been scheduled. 262 // Call DidSchedule() to indicate that this task has been scheduled.
252 // Note: This is only for debugging purposes. 263 // Note: This is only for debugging purposes.
253 task->DidSchedule(); 264 task->DidSchedule();
254 265
255 if (!node->num_dependencies()) 266 if (!node->num_dependencies())
256 new_ready_to_run_tasks.push(node); 267 new_ready_to_run_tasks.push(node);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 base::AutoUnlock unlock(lock_); 340 base::AutoUnlock unlock(lock_);
330 341
331 task->RunOnWorkerThread(thread_index); 342 task->RunOnWorkerThread(thread_index);
332 } 343 }
333 344
334 // This will mark task as finished running. 345 // This will mark task as finished running.
335 task->DidRun(); 346 task->DidRun();
336 347
337 // Now iterate over all dependents to remove dependency and check 348 // Now iterate over all dependents to remove dependency and check
338 // if they are ready to run. 349 // if they are ready to run.
339 scoped_ptr<GraphNode> node = running_tasks_.take_and_erase(task.get()); 350 scoped_ptr<internal::GraphNode> node = running_tasks_.take_and_erase(
351 task.get());
340 if (node) { 352 if (node) {
341 for (GraphNode::Vector::const_iterator it = node->dependents().begin(); 353 for (internal::GraphNode::Vector::const_iterator it =
354 node->dependents().begin();
342 it != node->dependents().end(); ++it) { 355 it != node->dependents().end(); ++it) {
343 GraphNode* dependent_node = *it; 356 internal::GraphNode* dependent_node = *it;
344 357
345 dependent_node->remove_dependency(); 358 dependent_node->remove_dependency();
346 // Task is ready if it has no dependencies. Add it to 359 // Task is ready if it has no dependencies. Add it to
347 // |ready_to_run_tasks_|. 360 // |ready_to_run_tasks_|.
348 if (!dependent_node->num_dependencies()) 361 if (!dependent_node->num_dependencies())
349 ready_to_run_tasks_.push(dependent_node); 362 ready_to_run_tasks_.push(dependent_node);
350 } 363 }
351 } 364 }
352 365
353 // Finally add task to |completed_tasks_|. 366 // Finally add task to |completed_tasks_|.
354 completed_tasks_.push_back(task); 367 completed_tasks_.push_back(task);
355 } 368 }
356 369
357 // We noticed we should exit. Wake up the next worker so it knows it should 370 // We noticed we should exit. Wake up the next worker so it knows it should
358 // exit as well (because the Shutdown() code only signals once). 371 // exit as well (because the Shutdown() code only signals once).
359 has_ready_to_run_tasks_cv_.Signal(); 372 has_ready_to_run_tasks_cv_.Signal();
360 } 373 }
361 374
362 WorkerPool::GraphNode::GraphNode()
363 : task_(NULL),
364 priority_(0),
365 num_dependencies_(0) {
366 }
367
368 WorkerPool::GraphNode::~GraphNode() {
369 }
370
371 WorkerPool::WorkerPool(size_t num_threads, 375 WorkerPool::WorkerPool(size_t num_threads,
372 const std::string& thread_name_prefix) 376 const std::string& thread_name_prefix)
373 : in_dispatch_completion_callbacks_(false), 377 : in_dispatch_completion_callbacks_(false),
374 inner_(make_scoped_ptr(new Inner(num_threads, thread_name_prefix))) { 378 inner_(make_scoped_ptr(new Inner(num_threads, thread_name_prefix))) {
375 } 379 }
376 380
377 WorkerPool::~WorkerPool() { 381 WorkerPool::~WorkerPool() {
378 } 382 }
379 383
380 void WorkerPool::Shutdown() { 384 void WorkerPool::Shutdown() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 void WorkerPool::SetTaskGraph(TaskGraph* graph) { 422 void WorkerPool::SetTaskGraph(TaskGraph* graph) {
419 TRACE_EVENT1("cc", "WorkerPool::SetTaskGraph", 423 TRACE_EVENT1("cc", "WorkerPool::SetTaskGraph",
420 "num_tasks", graph->size()); 424 "num_tasks", graph->size());
421 425
422 DCHECK(!in_dispatch_completion_callbacks_); 426 DCHECK(!in_dispatch_completion_callbacks_);
423 427
424 inner_->SetTaskGraph(graph); 428 inner_->SetTaskGraph(graph);
425 } 429 }
426 430
427 } // namespace cc 431 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/worker_pool.h ('k') | cc/resources/worker_pool_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698