Chromium Code Reviews| 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 |