Index: cc/resources/task_graph_runner.h |
diff --git a/cc/resources/task_graph_runner.h b/cc/resources/task_graph_runner.h |
index 5a55f6d30e3f686f1d9d3fff5df95e2bc8322f5b..722335a9801455dbdbde2237f52b8adf32ce91d7 100644 |
--- a/cc/resources/task_graph_runner.h |
+++ b/cc/resources/task_graph_runner.h |
@@ -5,13 +5,11 @@ |
#ifndef CC_RESOURCES_TASK_GRAPH_RUNNER_H_ |
#define CC_RESOURCES_TASK_GRAPH_RUNNER_H_ |
-#include <queue> |
#include <string> |
#include <vector> |
#include "base/containers/scoped_ptr_hash_map.h" |
#include "base/memory/ref_counted.h" |
-#include "base/memory/scoped_ptr.h" |
#include "base/synchronization/condition_variable.h" |
#include "base/threading/simple_thread.h" |
#include "cc/base/cc_export.h" |
@@ -39,58 +37,49 @@ class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> { |
bool did_run_; |
}; |
-} // namespace internal |
-} // namespace cc |
+// Dependencies are represented as edges in a task graph. Each graph node |
+// is assigned a priority and a run count that matches the number of |
+// dependencies. |
+struct CC_EXPORT TaskGraph { |
+ struct Node { |
+ class TaskComparator { |
+ public: |
+ explicit TaskComparator(const Task* task) : task_(task) {} |
-#if defined(COMPILER_GCC) |
-namespace BASE_HASH_NAMESPACE { |
-template <> |
-struct hash<cc::internal::Task*> { |
- size_t operator()(cc::internal::Task* ptr) const { |
- return hash<size_t>()(reinterpret_cast<size_t>(ptr)); |
- } |
-}; |
-} // namespace BASE_HASH_NAMESPACE |
-#endif // COMPILER |
+ bool operator()(const Node& node) const { return node.task == task_; } |
-namespace cc { |
-namespace internal { |
+ private: |
+ const Task* task_; |
+ }; |
-// Dependencies are represented by edges in a task graph. A graph node |
-// store edges as a vector of dependents. Each graph node is assigned |
-// a priority and a run count that matches the number of dependencies. |
-class CC_EXPORT GraphNode { |
- public: |
- typedef std::vector<GraphNode*> Vector; |
- typedef base::ScopedPtrHashMap<Task*, GraphNode> Map; |
+ typedef std::vector<Node> Vector; |
- GraphNode(Task* task, unsigned priority); |
- ~GraphNode(); |
+ Node(Task* task, unsigned priority, size_t dependencies) |
+ : task(task), priority(priority), dependencies(dependencies) {} |
- Task* task() { return task_; } |
+ Task* task; |
+ unsigned priority; |
+ size_t dependencies; |
+ }; |
- void add_dependent(GraphNode* dependent) { |
- DCHECK(dependent); |
- dependents_.push_back(dependent); |
- } |
- const Vector& dependents() const { return dependents_; } |
+ struct Edge { |
+ typedef std::vector<Edge> Vector; |
- unsigned priority() const { return priority_; } |
+ Edge(const Task* task, Task* dependent) |
+ : task(task), dependent(dependent) {} |
- unsigned num_dependencies() const { return num_dependencies_; } |
- void add_dependency() { ++num_dependencies_; } |
- void remove_dependency() { |
- DCHECK(num_dependencies_); |
- --num_dependencies_; |
- } |
+ const Task* task; |
+ Task* dependent; |
+ }; |
- private: |
- Task* task_; |
- Vector dependents_; |
- unsigned priority_; |
- unsigned num_dependencies_; |
+ TaskGraph(); |
+ ~TaskGraph(); |
+ |
+ void Swap(TaskGraph* other); |
+ void Reset(); |
- DISALLOW_COPY_AND_ASSIGN(GraphNode); |
+ Node::Vector nodes; |
+ Edge::Vector edges; |
}; |
class TaskGraphRunner; |
@@ -115,8 +104,6 @@ class CC_EXPORT NamespaceToken { |
// might block and should not be used on a thread that needs to be responsive. |
class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate { |
public: |
- typedef GraphNode::Map TaskGraph; |
- |
TaskGraphRunner(size_t num_threads, const std::string& thread_name_prefix); |
virtual ~TaskGraphRunner(); |
@@ -128,7 +115,7 @@ class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate { |
// no longer needed will be canceled unless already running. Canceled |
// tasks are moved to |completed_tasks| without being run. The result |
// is that once scheduled, a task is guaranteed to end up in the |
- // |completed_tasks| queue even if it later get canceled by another |
+ // |completed_tasks| queue even if it later gets canceled by another |
// call to SetTaskGraph(). |
void SetTaskGraph(NamespaceToken token, TaskGraph* graph); |
@@ -144,32 +131,41 @@ class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate { |
bool RunTaskForTesting(); |
private: |
+ struct PrioritizedTask { |
+ typedef std::vector<PrioritizedTask> Vector; |
+ |
+ PrioritizedTask(Task* task, unsigned priority) |
+ : task(task), priority(priority) {} |
+ |
+ Task* task; |
+ unsigned priority; |
+ }; |
+ |
struct TaskNamespace { |
typedef std::vector<TaskNamespace*> Vector; |
TaskNamespace(); |
~TaskNamespace(); |
- // This set contains all pending tasks. |
- TaskGraph pending_tasks; |
- // This set contains all currently running tasks. |
- TaskGraph running_tasks; |
+ // Current task graph. |
+ TaskGraph graph; |
+ |
+ // Ordered set of tasks that are ready to run. |
+ PrioritizedTask::Vector ready_to_run_tasks; |
+ |
// Completed tasks not yet collected by origin thread. |
Task::Vector completed_tasks; |
- // Ordered set of tasks that are ready to run. |
- internal::GraphNode::Vector ready_to_run_tasks; |
+ |
+ // Number of currently running tasks. |
+ size_t num_running_tasks; |
}; |
typedef base::ScopedPtrHashMap<int, TaskNamespace> TaskNamespaceMap; |
- static bool CompareTaskPriority(const internal::GraphNode* a, |
- const internal::GraphNode* b) { |
+ static bool CompareTaskPriority(const PrioritizedTask& a, |
+ const PrioritizedTask& b) { |
// In this system, numerically lower priority is run first. |
- if (a->priority() != b->priority()) |
- return a->priority() > b->priority(); |
- |
- // Run task with most dependents first when priority is the same. |
- return a->dependents().size() < b->dependents().size(); |
+ return a.priority > b.priority; |
} |
static bool CompareTaskNamespacePriority(const TaskNamespace* a, |
@@ -185,9 +181,9 @@ class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate { |
} |
static bool HasFinishedRunningTasksInNamespace( |
- TaskNamespace* task_namespace) { |
- return task_namespace->pending_tasks.empty() && |
- task_namespace->running_tasks.empty(); |
+ const TaskNamespace* task_namespace) { |
+ return !task_namespace->num_running_tasks && |
+ task_namespace->ready_to_run_tasks.empty(); |
} |
// Overridden from base::DelegateSimpleThread: |
@@ -224,6 +220,10 @@ class CC_EXPORT TaskGraphRunner : public base::DelegateSimpleThread::Delegate { |
// loop index is 0. |
unsigned next_thread_index_; |
+ // This set contains all currently running tasks. |
+ typedef std::vector<const Task*> TaskVector; |
+ TaskVector running_tasks_; |
+ |
// Set during shutdown. Tells workers to exit when no more tasks |
// are pending. |
bool shutdown_; |