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

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: rebase 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
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 #if defined(OS_ANDROID) 7 #if defined(OS_ANDROID)
8 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 8 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
9 #include <sys/resource.h> 9 #include <sys/resource.h>
10 #endif 10 #endif
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 } 62 }
63 63
64 bool WorkerPoolTask::HasFinishedRunning() const { 64 bool WorkerPoolTask::HasFinishedRunning() const {
65 return did_run_; 65 return did_run_;
66 } 66 }
67 67
68 bool WorkerPoolTask::HasCompleted() const { 68 bool WorkerPoolTask::HasCompleted() const {
69 return did_complete_; 69 return did_complete_;
70 } 70 }
71 71
72 GraphNode::GraphNode(internal::WorkerPoolTask* task, unsigned priority)
73 : task_(task),
74 priority_(priority),
75 num_dependencies_(0) {
76 }
77
78 GraphNode::~GraphNode() {
79 }
80
72 } // namespace internal 81 } // namespace internal
73 82
74 // Internal to the worker pool. Any data or logic that needs to be 83 // Internal to the worker pool. Any data or logic that needs to be
75 // shared between threads lives in this class. All members are guarded 84 // shared between threads lives in this class. All members are guarded
76 // by |lock_|. 85 // by |lock_|.
77 class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate { 86 class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
78 public: 87 public:
79 Inner(size_t num_threads, const std::string& thread_name_prefix); 88 Inner(size_t num_threads, const std::string& thread_name_prefix);
80 virtual ~Inner(); 89 virtual ~Inner();
81 90
82 void Shutdown(); 91 void Shutdown();
83 92
84 // Schedule running of tasks in |graph|. Tasks previously scheduled but 93 // Schedule running of tasks in |graph|. Tasks previously scheduled but
85 // no longer needed will be canceled unless already running. Canceled 94 // no longer needed will be canceled unless already running. Canceled
86 // tasks are moved to |completed_tasks_| without being run. The result 95 // tasks are moved to |completed_tasks_| without being run. The result
87 // is that once scheduled, a task is guaranteed to end up in the 96 // is that once scheduled, a task is guaranteed to end up in the
88 // |completed_tasks_| queue even if they later get canceled by another 97 // |completed_tasks_| queue even if they later get canceled by another
89 // call to SetTaskGraph(). 98 // call to SetTaskGraph().
90 void SetTaskGraph(TaskGraph* graph); 99 void SetTaskGraph(TaskGraph* graph);
91 100
92 // Collect all completed tasks in |completed_tasks|. 101 // Collect all completed tasks in |completed_tasks|.
93 void CollectCompletedTasks(TaskVector* completed_tasks); 102 void CollectCompletedTasks(TaskVector* completed_tasks);
94 103
95 private: 104 private:
96 class PriorityComparator { 105 class PriorityComparator {
97 public: 106 public:
98 bool operator()(const GraphNode* a, 107 bool operator()(const internal::GraphNode* a,
99 const GraphNode* b) { 108 const internal::GraphNode* b) {
100 // In this system, numerically lower priority is run first. 109 // In this system, numerically lower priority is run first.
101 return a->priority() > b->priority(); 110 return a->priority() > b->priority();
102 } 111 }
103 }; 112 };
104 113
105 // Overridden from base::DelegateSimpleThread: 114 // Overridden from base::DelegateSimpleThread:
106 virtual void Run() OVERRIDE; 115 virtual void Run() OVERRIDE;
107 116
108 // This lock protects all members of this class except 117 // This lock protects all members of this class except
109 // |worker_pool_on_origin_thread_|. Do not read or modify anything 118 // |worker_pool_on_origin_thread_|. Do not read or modify anything
110 // without holding this lock. Do not block while holding this lock. 119 // without holding this lock. Do not block while holding this lock.
111 mutable base::Lock lock_; 120 mutable base::Lock lock_;
112 121
113 // Condition variable that is waited on by worker threads until new 122 // Condition variable that is waited on by worker threads until new
114 // tasks are ready to run or shutdown starts. 123 // tasks are ready to run or shutdown starts.
115 base::ConditionVariable has_ready_to_run_tasks_cv_; 124 base::ConditionVariable has_ready_to_run_tasks_cv_;
116 125
117 // Provides each running thread loop with a unique index. First thread 126 // Provides each running thread loop with a unique index. First thread
118 // loop index is 0. 127 // loop index is 0.
119 unsigned next_thread_index_; 128 unsigned next_thread_index_;
120 129
121 // Set during shutdown. Tells workers to exit when no more tasks 130 // Set during shutdown. Tells workers to exit when no more tasks
122 // are pending. 131 // are pending.
123 bool shutdown_; 132 bool shutdown_;
124 133
125 // This set contains all pending tasks. 134 // This set contains all pending tasks.
126 GraphNodeMap pending_tasks_; 135 GraphNodeMap pending_tasks_;
127 136
128 // Ordered set of tasks that are ready to run. 137 // Ordered set of tasks that are ready to run.
129 typedef std::priority_queue<GraphNode*, 138 typedef std::priority_queue<internal::GraphNode*,
130 std::vector<GraphNode*>, 139 std::vector<internal::GraphNode*>,
131 PriorityComparator> TaskQueue; 140 PriorityComparator> TaskQueue;
132 TaskQueue ready_to_run_tasks_; 141 TaskQueue ready_to_run_tasks_;
133 142
134 // This set contains all currently running tasks. 143 // This set contains all currently running tasks.
135 GraphNodeMap running_tasks_; 144 GraphNodeMap running_tasks_;
136 145
137 // Completed tasks not yet collected by origin thread. 146 // Completed tasks not yet collected by origin thread.
138 TaskVector completed_tasks_; 147 TaskVector completed_tasks_;
139 148
140 ScopedPtrDeque<base::DelegateSimpleThread> workers_; 149 ScopedPtrDeque<base::DelegateSimpleThread> workers_;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 216
208 { 217 {
209 base::AutoLock lock(lock_); 218 base::AutoLock lock(lock_);
210 219
211 // First remove all completed tasks from |new_pending_tasks| and 220 // First remove all completed tasks from |new_pending_tasks| and
212 // adjust number of dependencies. 221 // adjust number of dependencies.
213 for (TaskVector::iterator it = completed_tasks_.begin(); 222 for (TaskVector::iterator it = completed_tasks_.begin();
214 it != completed_tasks_.end(); ++it) { 223 it != completed_tasks_.end(); ++it) {
215 internal::WorkerPoolTask* task = it->get(); 224 internal::WorkerPoolTask* task = it->get();
216 225
217 scoped_ptr<GraphNode> node = new_pending_tasks.take_and_erase(task); 226 scoped_ptr<internal::GraphNode> node = new_pending_tasks.take_and_erase(
227 task);
218 if (node) { 228 if (node) {
219 for (GraphNode::Vector::const_iterator it = node->dependents().begin(); 229 for (internal::GraphNode::Vector::const_iterator it =
230 node->dependents().begin();
220 it != node->dependents().end(); ++it) { 231 it != node->dependents().end(); ++it) {
221 GraphNode* dependent_node = *it; 232 internal::GraphNode* dependent_node = *it;
222 dependent_node->remove_dependency(); 233 dependent_node->remove_dependency();
223 } 234 }
224 } 235 }
225 } 236 }
226 237
227 // Move tasks not present in |new_pending_tasks| to |completed_tasks_|. 238 // Move tasks not present in |new_pending_tasks| to |completed_tasks_|.
228 for (GraphNodeMap::iterator it = pending_tasks_.begin(); 239 for (GraphNodeMap::iterator it = pending_tasks_.begin();
229 it != pending_tasks_.end(); ++it) { 240 it != pending_tasks_.end(); ++it) {
230 internal::WorkerPoolTask* task = it->first; 241 internal::WorkerPoolTask* task = it->first;
231 242
(...skipping 12 matching lines...) Expand all
244 // the right in both cases. 255 // the right in both cases.
245 new_running_tasks.set(task, new_pending_tasks.take_and_erase(task)); 256 new_running_tasks.set(task, new_pending_tasks.take_and_erase(task));
246 } 257 }
247 258
248 // Build new "ready to run" tasks queue. 259 // Build new "ready to run" tasks queue.
249 // TODO(reveman): Create this queue when building the task graph instead. 260 // TODO(reveman): Create this queue when building the task graph instead.
250 for (GraphNodeMap::iterator it = new_pending_tasks.begin(); 261 for (GraphNodeMap::iterator it = new_pending_tasks.begin();
251 it != new_pending_tasks.end(); ++it) { 262 it != new_pending_tasks.end(); ++it) {
252 internal::WorkerPoolTask* task = it->first; 263 internal::WorkerPoolTask* task = it->first;
253 DCHECK(task); 264 DCHECK(task);
254 GraphNode* node = it->second; 265 internal::GraphNode* node = it->second;
255 266
256 // Completed tasks should not exist in |new_pending_tasks|. 267 // Completed tasks should not exist in |new_pending_tasks|.
257 DCHECK(!task->HasFinishedRunning()); 268 DCHECK(!task->HasFinishedRunning());
258 269
259 // Call DidSchedule() to indicate that this task has been scheduled. 270 // Call DidSchedule() to indicate that this task has been scheduled.
260 // Note: This is only for debugging purposes. 271 // Note: This is only for debugging purposes.
261 task->DidSchedule(); 272 task->DidSchedule();
262 273
263 if (!node->num_dependencies()) 274 if (!node->num_dependencies())
264 new_ready_to_run_tasks.push(node); 275 new_ready_to_run_tasks.push(node);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 base::AutoUnlock unlock(lock_); 342 base::AutoUnlock unlock(lock_);
332 343
333 task->RunOnWorkerThread(thread_index); 344 task->RunOnWorkerThread(thread_index);
334 } 345 }
335 346
336 // This will mark task as finished running. 347 // This will mark task as finished running.
337 task->DidRun(); 348 task->DidRun();
338 349
339 // Now iterate over all dependents to remove dependency and check 350 // Now iterate over all dependents to remove dependency and check
340 // if they are ready to run. 351 // if they are ready to run.
341 scoped_ptr<GraphNode> node = running_tasks_.take_and_erase(task.get()); 352 scoped_ptr<internal::GraphNode> node = running_tasks_.take_and_erase(
353 task.get());
342 if (node) { 354 if (node) {
343 for (GraphNode::Vector::const_iterator it = node->dependents().begin(); 355 for (internal::GraphNode::Vector::const_iterator it =
356 node->dependents().begin();
344 it != node->dependents().end(); ++it) { 357 it != node->dependents().end(); ++it) {
345 GraphNode* dependent_node = *it; 358 internal::GraphNode* dependent_node = *it;
346 359
347 dependent_node->remove_dependency(); 360 dependent_node->remove_dependency();
348 // Dependent is not ready unless number of dependencies are 0. 361 // Dependent is not ready unless number of dependencies are 0.
349 if (dependent_node->num_dependencies()) 362 if (dependent_node->num_dependencies())
350 continue; 363 continue;
351 364
352 // Task is ready. Add it to |ready_to_run_tasks_|. 365 // Task is ready. Add it to |ready_to_run_tasks_|.
353 ready_to_run_tasks_.push(dependent_node); 366 ready_to_run_tasks_.push(dependent_node);
354 } 367 }
355 } 368 }
356 369
357 // Finally add task to |completed_tasks_|. 370 // Finally add task to |completed_tasks_|.
358 completed_tasks_.push_back(task); 371 completed_tasks_.push_back(task);
359 } 372 }
360 373
361 // We noticed we should exit. Wake up the next worker so it knows it should 374 // We noticed we should exit. Wake up the next worker so it knows it should
362 // exit as well (because the Shutdown() code only signals once). 375 // exit as well (because the Shutdown() code only signals once).
363 has_ready_to_run_tasks_cv_.Signal(); 376 has_ready_to_run_tasks_cv_.Signal();
364 } 377 }
365 378
366 WorkerPool::GraphNode::GraphNode()
367 : task_(NULL),
368 priority_(0),
369 num_dependencies_(0) {
370 }
371
372 WorkerPool::GraphNode::~GraphNode() {
373 }
374
375 WorkerPool::WorkerPool(size_t num_threads, 379 WorkerPool::WorkerPool(size_t num_threads,
376 const std::string& thread_name_prefix) 380 const std::string& thread_name_prefix)
377 : in_dispatch_completion_callbacks_(false), 381 : in_dispatch_completion_callbacks_(false),
378 inner_(make_scoped_ptr(new Inner(num_threads, thread_name_prefix))) { 382 inner_(make_scoped_ptr(new Inner(num_threads, thread_name_prefix))) {
379 } 383 }
380 384
381 WorkerPool::~WorkerPool() { 385 WorkerPool::~WorkerPool() {
382 } 386 }
383 387
384 void WorkerPool::Shutdown() { 388 void WorkerPool::Shutdown() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 void WorkerPool::SetTaskGraph(TaskGraph* graph) { 426 void WorkerPool::SetTaskGraph(TaskGraph* graph) {
423 TRACE_EVENT1("cc", "WorkerPool::SetTaskGraph", 427 TRACE_EVENT1("cc", "WorkerPool::SetTaskGraph",
424 "num_tasks", graph->size()); 428 "num_tasks", graph->size());
425 429
426 DCHECK(!in_dispatch_completion_callbacks_); 430 DCHECK(!in_dispatch_completion_callbacks_);
427 431
428 inner_->SetTaskGraph(graph); 432 inner_->SetTaskGraph(graph);
429 } 433 }
430 434
431 } // namespace cc 435 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698