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

Side by Side Diff: cc/resources/task_graph_runner.h

Issue 141163019: Re-land: cc: Remove WorkerPool class and instead use TaskGraphRunner directly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix mode of task_graph_runner.h Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « cc/resources/raster_worker_pool_unittest.cc ('k') | cc/resources/task_graph_runner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef CC_RESOURCES_TASK_GRAPH_RUNNER_H_
6 #define CC_RESOURCES_TASK_GRAPH_RUNNER_H_
7
8 #include <queue>
9 #include <string>
10 #include <vector>
11
12 #include "base/containers/scoped_ptr_hash_map.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/synchronization/condition_variable.h"
16 #include "base/threading/simple_thread.h"
17 #include "cc/base/cc_export.h"
18 #include "cc/base/scoped_ptr_deque.h"
19
20 namespace cc {
21 namespace internal {
22
23 class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> {
24 public:
25 typedef std::vector<scoped_refptr<Task> > Vector;
26
27 virtual void RunOnWorkerThread(unsigned thread_index) = 0;
28
29 void DidSchedule();
30 void WillRun();
31 void DidRun();
32
33 bool HasFinishedRunning() const;
34
35 protected:
36 friend class base::RefCountedThreadSafe<Task>;
37
38 Task();
39 virtual ~Task();
40
41 bool did_schedule_;
42 bool did_run_;
43 };
44
45 } // namespace internal
46 } // namespace cc
47
48 #if defined(COMPILER_GCC)
49 namespace BASE_HASH_NAMESPACE {
50 template <> struct hash<cc::internal::Task*> {
51 size_t operator()(cc::internal::Task* ptr) const {
52 return hash<size_t>()(reinterpret_cast<size_t>(ptr));
53 }
54 };
55 } // namespace BASE_HASH_NAMESPACE
56 #endif // COMPILER
57
58 namespace cc {
59 namespace internal {
60
61 // Dependencies are represented by edges in a task graph. A graph node
62 // store edges as a vector of dependents. Each graph node is assigned
63 // a priority and a run count that matches the number of dependencies.
64 class CC_EXPORT GraphNode {
65 public:
66 typedef std::vector<GraphNode*> Vector;
67 typedef base::ScopedPtrHashMap<Task*, GraphNode> Map;
68
69 GraphNode(Task* task, unsigned priority);
70 ~GraphNode();
71
72 Task* task() { return task_; }
73
74 void add_dependent(GraphNode* dependent) {
75 DCHECK(dependent);
76 dependents_.push_back(dependent);
77 }
78 const Vector& dependents() const { return dependents_; }
79
80 unsigned priority() const { return priority_; }
81
82 unsigned num_dependencies() const { return num_dependencies_; }
83 void add_dependency() { ++num_dependencies_; }
84 void remove_dependency() {
85 DCHECK(num_dependencies_);
86 --num_dependencies_;
87 }
88
89 private:
90 Task* task_;
91 Vector dependents_;
92 unsigned priority_;
93 unsigned num_dependencies_;
94
95 DISALLOW_COPY_AND_ASSIGN(GraphNode);
96 };
97
98 class TaskGraphRunner;
99
100 // Opaque identifier that defines a namespace of tasks.
101 class CC_EXPORT NamespaceToken {
102 public:
103 NamespaceToken() : id_(0) {}
104 ~NamespaceToken() {}
105
106 bool IsValid() const {
107 return id_ != 0;
108 }
109
110 private:
111 friend class TaskGraphRunner;
112
113 explicit NamespaceToken(int id) : id_(id) {}
114
115 int id_;
116 };
117
118 // A worker thread pool that runs tasks provided by task graph. Destructor
119 // might block and should not be used on a thread that needs to be responsive.
120 class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate {
121 public:
122 typedef GraphNode::Map TaskGraph;
123
124 TaskGraphRunner(size_t num_threads, const std::string& thread_name_prefix);
125 virtual ~TaskGraphRunner();
126
127 // Returns a unique token that can be used to pass a task graph to
128 // SetTaskGraph(). Valid tokens are always nonzero.
129 NamespaceToken GetNamespaceToken();
130
131 // Schedule running of tasks in |graph|. Tasks previously scheduled but
132 // no longer needed will be canceled unless already running. Canceled
133 // tasks are moved to |completed_tasks| without being run. The result
134 // is that once scheduled, a task is guaranteed to end up in the
135 // |completed_tasks| queue even if it later get canceled by another
136 // call to SetTaskGraph().
137 void SetTaskGraph(NamespaceToken token, TaskGraph* graph);
138
139 // Wait for all scheduled tasks to finish running.
140 void WaitForTasksToFinishRunning(NamespaceToken token);
141
142 // Collect all completed tasks in |completed_tasks|.
143 void CollectCompletedTasks(
144 NamespaceToken token, Task::Vector* completed_tasks);
145
146 private:
147 struct TaskNamespace {
148 typedef std::vector<TaskNamespace*> Vector;
149
150 TaskNamespace();
151 ~TaskNamespace();
152
153 // This set contains all pending tasks.
154 TaskGraph pending_tasks;
155 // This set contains all currently running tasks.
156 TaskGraph running_tasks;
157 // Completed tasks not yet collected by origin thread.
158 Task::Vector completed_tasks;
159 // Ordered set of tasks that are ready to run.
160 internal::GraphNode::Vector ready_to_run_tasks;
161 };
162
163 typedef base::ScopedPtrHashMap<int, TaskNamespace> TaskNamespaceMap;
164
165 static bool CompareTaskPriority(const internal::GraphNode* a,
166 const internal::GraphNode* b) {
167 // In this system, numerically lower priority is run first.
168 if (a->priority() != b->priority())
169 return a->priority() > b->priority();
170
171 // Run task with most dependents first when priority is the same.
172 return a->dependents().size() < b->dependents().size();
173 }
174
175 static bool CompareTaskNamespacePriority(const TaskNamespace* a,
176 const TaskNamespace* b) {
177 DCHECK(!a->ready_to_run_tasks.empty());
178 DCHECK(!b->ready_to_run_tasks.empty());
179
180 // Compare based on task priority of the ready_to_run_tasks heap
181 // .front() will hold the max element of the heap,
182 // except after pop_heap, when max element is moved to .back().
183 return CompareTaskPriority(a->ready_to_run_tasks.front(),
184 b->ready_to_run_tasks.front());
185 }
186
187 static bool HasFinishedRunningTasksInNamespace(
188 TaskNamespace* task_namespace) {
189 return task_namespace->pending_tasks.empty() &&
190 task_namespace->running_tasks.empty();
191 }
192
193 // Overridden from base::DelegateSimpleThread:
194 virtual void Run() OVERRIDE;
195
196 // This lock protects all members of this class. Do not read or modify
197 // anything without holding this lock. Do not block while holding this
198 // lock.
199 mutable base::Lock lock_;
200
201 // Condition variable that is waited on by worker threads until new
202 // tasks are ready to run or shutdown starts.
203 base::ConditionVariable has_ready_to_run_tasks_cv_;
204
205 // Condition variable that is waited on by origin threads until a
206 // namespace has finished running all associated tasks.
207 base::ConditionVariable has_namespaces_with_finished_running_tasks_cv_;
208
209 // Provides a unique id to each NamespaceToken.
210 int next_namespace_id_;
211
212 // This set contains all namespaces with pending, running or completed
213 // tasks not yet collected.
214 TaskNamespaceMap namespaces_;
215
216 // Ordered set of task namespaces that have ready to run tasks.
217 TaskNamespace::Vector ready_to_run_namespaces_;
218
219 // Provides each running thread loop with a unique index. First thread
220 // loop index is 0.
221 unsigned next_thread_index_;
222
223 // Set during shutdown. Tells workers to exit when no more tasks
224 // are pending.
225 bool shutdown_;
226
227 ScopedPtrDeque<base::DelegateSimpleThread> workers_;
228
229 DISALLOW_COPY_AND_ASSIGN(TaskGraphRunner);
230 };
231
232 } // namespace internal
233 } // namespace cc
234
235 #endif // CC_RESOURCES_TASK_GRAPH_RUNNER_H_
OLDNEW
« no previous file with comments | « cc/resources/raster_worker_pool_unittest.cc ('k') | cc/resources/task_graph_runner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698