OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef CC_RESOURCES_TASK_GRAPH_RUNNER_H_ | 5 #ifndef CC_RESOURCES_TASK_GRAPH_RUNNER_H_ |
6 #define CC_RESOURCES_TASK_GRAPH_RUNNER_H_ | 6 #define CC_RESOURCES_TASK_GRAPH_RUNNER_H_ |
7 | 7 |
8 #include <array> | |
8 #include <map> | 9 #include <map> |
9 #include <vector> | 10 #include <vector> |
10 | 11 |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
13 #include "base/synchronization/condition_variable.h" | 14 #include "base/synchronization/condition_variable.h" |
14 #include "cc/base/cc_export.h" | 15 #include "cc/base/cc_export.h" |
15 | 16 |
16 namespace cc { | 17 namespace cc { |
17 | 18 |
(...skipping 28 matching lines...) Expand all Loading... | |
46 explicit TaskComparator(const Task* task) : task_(task) {} | 47 explicit TaskComparator(const Task* task) : task_(task) {} |
47 | 48 |
48 bool operator()(const Node& node) const { return node.task == task_; } | 49 bool operator()(const Node& node) const { return node.task == task_; } |
49 | 50 |
50 private: | 51 private: |
51 const Task* task_; | 52 const Task* task_; |
52 }; | 53 }; |
53 | 54 |
54 typedef std::vector<Node> Vector; | 55 typedef std::vector<Node> Vector; |
55 | 56 |
56 Node(Task* task, unsigned priority, size_t dependencies) | 57 Node(Task* task, |
57 : task(task), priority(priority), dependencies(dependencies) {} | 58 unsigned priority, |
danakj
2015/02/23 18:45:01
did git cl format do this? it seems to have disabl
| |
59 size_t dependencies, | |
60 int sub_namespace, | |
61 int max_concurrent_tasks) | |
62 : task(task), | |
63 priority(priority), | |
64 dependencies(dependencies), | |
65 sub_namespace(sub_namespace), | |
66 max_concurrent_tasks(max_concurrent_tasks) {} | |
58 | 67 |
59 Task* task; | 68 Task* task; |
60 unsigned priority; | 69 unsigned priority; |
61 size_t dependencies; | 70 size_t dependencies; |
71 int sub_namespace; | |
72 int max_concurrent_tasks; | |
62 }; | 73 }; |
63 | 74 |
64 struct Edge { | 75 struct Edge { |
65 typedef std::vector<Edge> Vector; | 76 typedef std::vector<Edge> Vector; |
66 | 77 |
67 Edge(const Task* task, Task* dependent) | 78 Edge(const Task* task, Task* dependent) |
68 : task(task), dependent(dependent) {} | 79 : task(task), dependent(dependent) {} |
69 | 80 |
70 const Task* task; | 81 const Task* task; |
71 Task* dependent; | 82 Task* dependent; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 | 145 |
135 // Signals the Run method to return when it becomes idle. It will continue to | 146 // Signals the Run method to return when it becomes idle. It will continue to |
136 // process tasks and future tasks as long as they are scheduled. | 147 // process tasks and future tasks as long as they are scheduled. |
137 // Warning: if the TaskGraphRunner remains busy, it may never quit. | 148 // Warning: if the TaskGraphRunner remains busy, it may never quit. |
138 void Shutdown(); | 149 void Shutdown(); |
139 | 150 |
140 private: | 151 private: |
141 struct PrioritizedTask { | 152 struct PrioritizedTask { |
142 typedef std::vector<PrioritizedTask> Vector; | 153 typedef std::vector<PrioritizedTask> Vector; |
143 | 154 |
144 PrioritizedTask(Task* task, unsigned priority) | 155 PrioritizedTask(Task* task, unsigned priority, int max_concurrent_tasks) |
145 : task(task), priority(priority) {} | 156 : task(task), |
157 priority(priority), | |
158 max_concurrent_tasks(max_concurrent_tasks) {} | |
146 | 159 |
147 Task* task; | 160 Task* task; |
148 unsigned priority; | 161 unsigned priority; |
162 int max_concurrent_tasks; | |
149 }; | 163 }; |
150 | 164 |
151 typedef std::vector<const Task*> TaskVector; | 165 typedef std::vector<const Task*> TaskVector; |
152 | 166 |
167 struct TaskNamespace; | |
168 | |
169 struct TaskSubNamespace { | |
170 typedef std::vector<TaskSubNamespace*> Vector; | |
danakj
2015/02/23 18:45:01
prefer using instead of typedef
| |
171 | |
172 TaskSubNamespace(); | |
173 ~TaskSubNamespace(); | |
174 bool IsReadyToRun() const; | |
175 | |
176 // Task namespace this belongs to. | |
177 TaskNamespace* task_namespace; | |
178 | |
179 bool is_in_ready_sub_namespaces; | |
180 | |
181 // Number of currently running tasks in this sub namespace. | |
182 int running_task_count; | |
183 | |
184 // Ordered set of tasks that are ready to run. | |
185 PrioritizedTask::Vector ready_to_run_tasks; | |
186 }; | |
187 | |
153 struct TaskNamespace { | 188 struct TaskNamespace { |
154 typedef std::vector<TaskNamespace*> Vector; | 189 typedef std::vector<TaskNamespace*> Vector; |
155 | 190 |
191 static const int kNumberOfSubNamespaces = 2; | |
danakj
2015/02/23 18:45:01
this 2 looks pretty magical here, is it possible t
| |
192 static const int kDefaultSubNamespace = 0; | |
danakj
2015/02/23 18:45:01
There's at least 2 constants with this name in thi
| |
193 | |
156 TaskNamespace(); | 194 TaskNamespace(); |
157 ~TaskNamespace(); | 195 ~TaskNamespace(); |
158 | 196 |
159 // Current task graph. | 197 // Current task graph. |
160 TaskGraph graph; | 198 TaskGraph graph; |
161 | 199 |
162 // Ordered set of tasks that are ready to run. | 200 typedef std::array<TaskSubNamespace, kNumberOfSubNamespaces> |
danakj
2015/02/23 18:45:01
std::array is c++11 library feature no? (ie can't
danakj
2015/02/23 18:45:01
using
| |
163 PrioritizedTask::Vector ready_to_run_tasks; | 201 SubNamespaceArray; |
202 SubNamespaceArray sub_namespaces; | |
164 | 203 |
165 // Completed tasks not yet collected by origin thread. | 204 // Completed tasks not yet collected by origin thread. |
166 Task::Vector completed_tasks; | 205 Task::Vector completed_tasks; |
167 | 206 |
168 // This set contains all currently running tasks. | 207 // This set contains all currently running tasks. |
169 TaskVector running_tasks; | 208 TaskVector running_tasks; |
170 }; | 209 }; |
171 | 210 |
172 typedef std::map<int, TaskNamespace> TaskNamespaceMap; | 211 typedef std::map<int, TaskNamespace> TaskNamespaceMap; |
173 | 212 |
174 static bool CompareTaskPriority(const PrioritizedTask& a, | 213 static bool CompareTaskPriority(const PrioritizedTask& a, |
175 const PrioritizedTask& b) { | 214 const PrioritizedTask& b) { |
176 // In this system, numerically lower priority is run first. | 215 // In this system, numerically lower priority is run first. |
177 return a.priority > b.priority; | 216 return a.priority > b.priority; |
178 } | 217 } |
179 | 218 |
180 static bool CompareTaskNamespacePriority(const TaskNamespace* a, | 219 static bool CompareTaskSubNamespacePriority(const TaskSubNamespace* a, |
181 const TaskNamespace* b) { | 220 const TaskSubNamespace* b) { |
182 DCHECK(!a->ready_to_run_tasks.empty()); | 221 DCHECK(!a->ready_to_run_tasks.empty()); |
183 DCHECK(!b->ready_to_run_tasks.empty()); | 222 DCHECK(!b->ready_to_run_tasks.empty()); |
184 | 223 |
185 // Compare based on task priority of the ready_to_run_tasks heap .front() | 224 // Compare based on task priority of the ready_to_run_tasks heap .front() |
186 // will hold the max element of the heap, except after pop_heap, when max | 225 // will hold the max element of the heap, except after pop_heap, when max |
187 // element is moved to .back(). | 226 // element is moved to .back(). |
188 return CompareTaskPriority(a->ready_to_run_tasks.front(), | 227 return CompareTaskPriority(a->ready_to_run_tasks.front(), |
189 b->ready_to_run_tasks.front()); | 228 b->ready_to_run_tasks.front()); |
190 } | 229 } |
191 | 230 |
192 static bool HasFinishedRunningTasksInNamespace( | 231 static bool HasFinishedRunningTasksInNamespace( |
193 const TaskNamespace* task_namespace) { | 232 const TaskNamespace* task_namespace) { |
194 return task_namespace->running_tasks.empty() && | 233 if (!task_namespace->running_tasks.empty()) |
195 task_namespace->ready_to_run_tasks.empty(); | 234 return false; |
235 for (const TaskSubNamespace& sub_namespace : | |
236 task_namespace->sub_namespaces) { | |
237 if (!sub_namespace.ready_to_run_tasks.empty()) | |
238 return false; | |
239 } | |
240 return true; | |
196 } | 241 } |
197 | 242 |
198 // Run next task. Caller must acquire |lock_| prior to calling this function | 243 // Run next task. Caller must acquire |lock_| prior to calling this function |
199 // and make sure at least one task is ready to run. | 244 // and make sure at least one task is ready to run. |
200 void RunTaskWithLockAcquired(); | 245 void RunTaskWithLockAcquired(); |
201 | 246 |
202 // This lock protects all members of this class. Do not read or modify | 247 // This lock protects all members of this class. Do not read or modify |
203 // anything without holding this lock. Do not block while holding this lock. | 248 // anything without holding this lock. Do not block while holding this lock. |
204 mutable base::Lock lock_; | 249 mutable base::Lock lock_; |
205 | 250 |
206 // Condition variable that is waited on by Run() until new tasks are ready to | 251 // Condition variable that is waited on by Run() until new tasks are ready to |
207 // run or shutdown starts. | 252 // run or shutdown starts. |
208 base::ConditionVariable has_ready_to_run_tasks_cv_; | 253 base::ConditionVariable has_ready_to_run_tasks_cv_; |
209 | 254 |
210 // Condition variable that is waited on by origin threads until a namespace | 255 // Condition variable that is waited on by origin threads until a namespace |
211 // has finished running all associated tasks. | 256 // has finished running all associated tasks. |
212 base::ConditionVariable has_namespaces_with_finished_running_tasks_cv_; | 257 base::ConditionVariable has_namespaces_with_finished_running_tasks_cv_; |
213 | 258 |
214 // Provides a unique id to each NamespaceToken. | 259 // Provides a unique id to each NamespaceToken. |
215 int next_namespace_id_; | 260 int next_namespace_id_; |
216 | 261 |
217 // This set contains all namespaces with pending, running or completed tasks | 262 // This set contains all namespaces with pending, running or completed tasks |
218 // not yet collected. | 263 // not yet collected. |
219 TaskNamespaceMap namespaces_; | 264 TaskNamespaceMap namespaces_; |
220 | 265 |
221 // Ordered set of task namespaces that have ready to run tasks. | 266 // Ordered set of task sub namespaces that have ready to run tasks. |
222 TaskNamespace::Vector ready_to_run_namespaces_; | 267 TaskSubNamespace::Vector ready_to_run_sub_namespaces_; |
223 | 268 |
224 // Set during shutdown. Tells Run() to return when no more tasks are pending. | 269 // Set during shutdown. Tells Run() to return when no more tasks are pending. |
225 bool shutdown_; | 270 bool shutdown_; |
226 | 271 |
227 DISALLOW_COPY_AND_ASSIGN(TaskGraphRunner); | 272 DISALLOW_COPY_AND_ASSIGN(TaskGraphRunner); |
228 }; | 273 }; |
229 | 274 |
230 } // namespace cc | 275 } // namespace cc |
231 | 276 |
232 #endif // CC_RESOURCES_TASK_GRAPH_RUNNER_H_ | 277 #endif // CC_RESOURCES_TASK_GRAPH_RUNNER_H_ |
OLD | NEW |