| OLD | NEW |
| (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_BASE_WORKER_POOL_H_ | |
| 6 #define CC_BASE_WORKER_POOL_H_ | |
| 7 | |
| 8 #include <deque> | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/cancelable_callback.h" | |
| 13 #include "base/memory/ref_counted.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/memory/weak_ptr.h" | |
| 16 #include "base/message_loop.h" | |
| 17 #include "cc/base/cc_export.h" | |
| 18 #include "cc/base/scoped_ptr_hash_map.h" | |
| 19 | |
| 20 namespace cc { | |
| 21 namespace internal { | |
| 22 | |
| 23 class CC_EXPORT WorkerPoolTask | |
| 24 : public base::RefCountedThreadSafe<WorkerPoolTask> { | |
| 25 public: | |
| 26 typedef std::vector<scoped_refptr<WorkerPoolTask> > TaskVector; | |
| 27 | |
| 28 virtual void RunOnThread(unsigned thread_index) = 0; | |
| 29 virtual void DispatchCompletionCallback() = 0; | |
| 30 | |
| 31 void DidSchedule(); | |
| 32 void WillRun(); | |
| 33 void DidRun(); | |
| 34 void DidComplete(); | |
| 35 | |
| 36 bool IsReadyToRun() const; | |
| 37 bool HasFinishedRunning() const; | |
| 38 bool HasCompleted() const; | |
| 39 | |
| 40 TaskVector& dependencies() { return dependencies_; } | |
| 41 | |
| 42 protected: | |
| 43 friend class base::RefCountedThreadSafe<WorkerPoolTask>; | |
| 44 | |
| 45 WorkerPoolTask(); | |
| 46 explicit WorkerPoolTask(TaskVector* dependencies); | |
| 47 virtual ~WorkerPoolTask(); | |
| 48 | |
| 49 private: | |
| 50 bool did_schedule_; | |
| 51 bool did_run_; | |
| 52 bool did_complete_; | |
| 53 TaskVector dependencies_; | |
| 54 }; | |
| 55 | |
| 56 } // namespace internal | |
| 57 } // namespace cc | |
| 58 | |
| 59 #if defined(COMPILER_GCC) | |
| 60 namespace BASE_HASH_NAMESPACE { | |
| 61 template <> struct hash<cc::internal::WorkerPoolTask*> { | |
| 62 size_t operator()(cc::internal::WorkerPoolTask* ptr) const { | |
| 63 return hash<size_t>()(reinterpret_cast<size_t>(ptr)); | |
| 64 } | |
| 65 }; | |
| 66 } // namespace BASE_HASH_NAMESPACE | |
| 67 #endif // COMPILER | |
| 68 | |
| 69 namespace cc { | |
| 70 | |
| 71 // A worker thread pool that runs tasks provided by task graph and | |
| 72 // guarantees completion of all pending tasks at shutdown. | |
| 73 class CC_EXPORT WorkerPool { | |
| 74 public: | |
| 75 virtual ~WorkerPool(); | |
| 76 | |
| 77 // Tells the worker pool to shutdown and returns once all pending tasks have | |
| 78 // completed. | |
| 79 virtual void Shutdown(); | |
| 80 | |
| 81 // Force a check for completed tasks. | |
| 82 virtual void CheckForCompletedTasks(); | |
| 83 | |
| 84 protected: | |
| 85 class CC_EXPORT GraphNode { | |
| 86 public: | |
| 87 GraphNode(internal::WorkerPoolTask* dependent, unsigned priority); | |
| 88 ~GraphNode(); | |
| 89 | |
| 90 void AddDependent(internal::WorkerPoolTask* dependent); | |
| 91 | |
| 92 const internal::WorkerPoolTask::TaskVector& dependents() const { | |
| 93 return dependents_; | |
| 94 } | |
| 95 unsigned priority() const { return priority_; } | |
| 96 | |
| 97 private: | |
| 98 internal::WorkerPoolTask::TaskVector dependents_; | |
| 99 unsigned priority_; | |
| 100 | |
| 101 DISALLOW_COPY_AND_ASSIGN(GraphNode); | |
| 102 }; | |
| 103 typedef ScopedPtrHashMap<internal::WorkerPoolTask*, GraphNode> GraphNodeMap; | |
| 104 typedef GraphNodeMap TaskGraph; | |
| 105 | |
| 106 WorkerPool(size_t num_threads, const std::string& thread_name_prefix); | |
| 107 | |
| 108 // Schedule running of tasks in |graph|. Any previously scheduled tasks | |
| 109 // that are not already running will be canceled. Canceled tasks don't run | |
| 110 // but completion of them is still processed. | |
| 111 void SetTaskGraph(TaskGraph* graph); | |
| 112 | |
| 113 // BuildTaskGraph() takes a task tree as input and constructs a | |
| 114 // unique set of tasks with edges between dependencies pointing in | |
| 115 // the direction of the dependents. Each task is given a unique priority | |
| 116 // which is currently the same as the DFS traversal order. | |
| 117 // | |
| 118 // Input: Output: | |
| 119 // | |
| 120 // root task4 Task | Priority (lower is better) | |
| 121 // / \ / \ -------+--------------------------- | |
| 122 // task1 task2 task3 task2 root | 4 | |
| 123 // | | | | task1 | 2 | |
| 124 // task3 | task1 | task2 | 3 | |
| 125 // | | \ / task3 | 1 | |
| 126 // task4 task4 root task4 | 0 | |
| 127 // | |
| 128 // The output can be used to efficiently maintain a queue of | |
| 129 // "ready to run" tasks. | |
| 130 static unsigned BuildTaskGraphRecursive( | |
| 131 internal::WorkerPoolTask* task, | |
| 132 internal::WorkerPoolTask* dependent, | |
| 133 unsigned priority, | |
| 134 TaskGraph* tasks); | |
| 135 static void BuildTaskGraph( | |
| 136 internal::WorkerPoolTask* root, TaskGraph* tasks); | |
| 137 | |
| 138 private: | |
| 139 class Inner; | |
| 140 friend class Inner; | |
| 141 | |
| 142 typedef std::deque<scoped_refptr<internal::WorkerPoolTask> > TaskDeque; | |
| 143 | |
| 144 void DispatchCompletionCallbacks(TaskDeque* completed_tasks); | |
| 145 | |
| 146 bool in_dispatch_completion_callbacks_; | |
| 147 | |
| 148 // Hide the gory details of the worker pool in |inner_|. | |
| 149 const scoped_ptr<Inner> inner_; | |
| 150 }; | |
| 151 | |
| 152 } // namespace cc | |
| 153 | |
| 154 #endif // CC_BASE_WORKER_POOL_H_ | |
| OLD | NEW |