| Index: cc/resources/worker_pool.cc
|
| diff --git a/cc/resources/worker_pool.cc b/cc/resources/worker_pool.cc
|
| index dca0c704f09dbc2559bf3f4adf860724ce9a6240..65134e21d539e75a871a0c63e191d2fec606fb0e 100644
|
| --- a/cc/resources/worker_pool.cc
|
| +++ b/cc/resources/worker_pool.cc
|
| @@ -5,7 +5,6 @@
|
| #include "cc/resources/worker_pool.h"
|
|
|
| #include <algorithm>
|
| -#include <queue>
|
|
|
| #include "base/bind.h"
|
| #include "base/containers/hash_tables.h"
|
| @@ -98,18 +97,15 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
|
| void CollectCompletedTasks(TaskVector* completed_tasks);
|
|
|
| private:
|
| - class PriorityComparator {
|
| - public:
|
| - bool operator()(const internal::GraphNode* a,
|
| - const internal::GraphNode* 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();
|
| - }
|
| - };
|
| + static bool CompareTaskPriority(const internal::GraphNode* a,
|
| + const internal::GraphNode* 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();
|
| + }
|
|
|
| // Overridden from base::DelegateSimpleThread:
|
| virtual void Run() OVERRIDE;
|
| @@ -134,11 +130,8 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate {
|
| // This set contains all pending tasks.
|
| GraphNodeMap pending_tasks_;
|
|
|
| - // Ordered set of tasks that are ready to run.
|
| - typedef std::priority_queue<internal::GraphNode*,
|
| - std::vector<internal::GraphNode*>,
|
| - PriorityComparator> TaskQueue;
|
| - TaskQueue ready_to_run_tasks_;
|
| + // Priority queue containing tasks that are ready to run.
|
| + internal::GraphNode::Vector ready_to_run_tasks_;
|
|
|
| // This set contains all currently running tasks.
|
| GraphNodeMap running_tasks_;
|
| @@ -213,7 +206,6 @@ void WorkerPool::Inner::SetTaskGraph(TaskGraph* graph) {
|
|
|
| GraphNodeMap new_pending_tasks;
|
| GraphNodeMap new_running_tasks;
|
| - TaskQueue new_ready_to_run_tasks;
|
|
|
| new_pending_tasks.swap(*graph);
|
|
|
| @@ -250,7 +242,7 @@ void WorkerPool::Inner::SetTaskGraph(TaskGraph* graph) {
|
| }
|
|
|
| // Build new "ready to run" tasks queue.
|
| - // TODO(reveman): Create this queue when building the task graph instead.
|
| + ready_to_run_tasks_.clear();
|
| for (GraphNodeMap::iterator it = new_pending_tasks.begin();
|
| it != new_pending_tasks.end(); ++it) {
|
| internal::WorkerPoolTask* task = it->first;
|
| @@ -265,12 +257,18 @@ void WorkerPool::Inner::SetTaskGraph(TaskGraph* graph) {
|
| task->DidSchedule();
|
|
|
| if (!node->num_dependencies())
|
| - new_ready_to_run_tasks.push(node);
|
| + ready_to_run_tasks_.push_back(node);
|
|
|
| // Erase the task from old pending tasks.
|
| pending_tasks_.erase(task);
|
| }
|
|
|
| + // Rearrange the elements in |ready_to_run_tasks_| in such a way that
|
| + // they form a heap.
|
| + std::make_heap(ready_to_run_tasks_.begin(),
|
| + ready_to_run_tasks_.end(),
|
| + CompareTaskPriority);
|
| +
|
| completed_tasks_.reserve(completed_tasks_.size() + pending_tasks_.size());
|
|
|
| // The items left in |pending_tasks_| need to be canceled.
|
| @@ -284,7 +282,6 @@ void WorkerPool::Inner::SetTaskGraph(TaskGraph* graph) {
|
| // Note: old tasks are intentionally destroyed after releasing |lock_|.
|
| pending_tasks_.swap(new_pending_tasks);
|
| running_tasks_.swap(new_running_tasks);
|
| - std::swap(ready_to_run_tasks_, new_ready_to_run_tasks);
|
|
|
| // If |ready_to_run_tasks_| is empty, it means we either have
|
| // running tasks, or we have no pending tasks.
|
| @@ -322,9 +319,12 @@ void WorkerPool::Inner::Run() {
|
| }
|
|
|
| // Take top priority task from |ready_to_run_tasks_|.
|
| + std::pop_heap(ready_to_run_tasks_.begin(),
|
| + ready_to_run_tasks_.end(),
|
| + CompareTaskPriority);
|
| scoped_refptr<internal::WorkerPoolTask> task(
|
| - ready_to_run_tasks_.top()->task());
|
| - ready_to_run_tasks_.pop();
|
| + ready_to_run_tasks_.back()->task());
|
| + ready_to_run_tasks_.pop_back();
|
|
|
| // Move task from |pending_tasks_| to |running_tasks_|.
|
| DCHECK(pending_tasks_.contains(task.get()));
|
| @@ -359,8 +359,12 @@ void WorkerPool::Inner::Run() {
|
| dependent_node->remove_dependency();
|
| // Task is ready if it has no dependencies. Add it to
|
| // |ready_to_run_tasks_|.
|
| - if (!dependent_node->num_dependencies())
|
| - ready_to_run_tasks_.push(dependent_node);
|
| + if (!dependent_node->num_dependencies()) {
|
| + ready_to_run_tasks_.push_back(dependent_node);
|
| + std::push_heap(ready_to_run_tasks_.begin(),
|
| + ready_to_run_tasks_.end(),
|
| + CompareTaskPriority);
|
| + }
|
| }
|
| }
|
|
|
|
|