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_RESOURCES_WORKER_POOL_H_ 6 #define CC_RESOURCES_WORKER_POOL_H_ 7 8 #include <deque> 9 #include <string> 10 #include <vector> 11 12 #include "base/cancelable_callback.h" 13 #include "base/containers/scoped_ptr_hash_map.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/message_loop/message_loop.h" 18 #include "cc/base/cc_export.h" 19 20 namespace cc { 21 namespace internal { 22 23 class CC_EXPORT WorkerPoolTask 24 : public base::RefCountedThreadSafe<WorkerPoolTask> { 25 public: 26 virtual void RunOnWorkerThread(unsigned thread_index) = 0; 27 virtual void CompleteOnOriginThread() = 0; 28 29 void DidSchedule(); 30 void WillRun(); 31 void DidRun(); 32 void WillComplete(); 33 void DidComplete(); 34 35 bool HasFinishedRunning() const; 36 bool HasCompleted() const; 37 38 protected: 39 friend class base::RefCountedThreadSafe<WorkerPoolTask>; 40 41 WorkerPoolTask(); 42 virtual ~WorkerPoolTask(); 43 44 private: 45 bool did_schedule_; 46 bool did_run_; 47 bool did_complete_; 48 }; 49 50 class CC_EXPORT GraphNode { 51 public: 52 typedef std::vector<GraphNode*> Vector; 53 54 GraphNode(internal::WorkerPoolTask* task, unsigned priority); 55 ~GraphNode(); 56 57 WorkerPoolTask* task() { return task_; } 58 59 void add_dependent(GraphNode* dependent) { 60 DCHECK(dependent); 61 dependents_.push_back(dependent); 62 } 63 const Vector& dependents() const { return dependents_; } 64 65 unsigned priority() const { return priority_; } 66 67 unsigned num_dependencies() const { return num_dependencies_; } 68 void add_dependency() { ++num_dependencies_; } 69 void remove_dependency() { 70 DCHECK(num_dependencies_); 71 --num_dependencies_; 72 } 73 74 private: 75 WorkerPoolTask* task_; 76 Vector dependents_; 77 unsigned priority_; 78 unsigned num_dependencies_; 79 80 DISALLOW_COPY_AND_ASSIGN(GraphNode); 81 }; 82 83 } // namespace internal 84 } // namespace cc 85 86 #if defined(COMPILER_GCC) 87 namespace BASE_HASH_NAMESPACE { 88 template <> struct hash<cc::internal::WorkerPoolTask*> { 89 size_t operator()(cc::internal::WorkerPoolTask* ptr) const { 90 return hash<size_t>()(reinterpret_cast<size_t>(ptr)); 91 } 92 }; 93 } // namespace BASE_HASH_NAMESPACE 94 #endif // COMPILER 95 96 namespace cc { 97 98 // A worker thread pool that runs tasks provided by task graph and 99 // guarantees completion of all pending tasks at shutdown. 100 class CC_EXPORT WorkerPool { 101 public: 102 virtual ~WorkerPool(); 103 104 // Tells the worker pool to shutdown and returns once all pending tasks have 105 // completed. 106 virtual void Shutdown(); 107 108 // Force a check for completed tasks. 109 virtual void CheckForCompletedTasks(); 110 111 protected: 112 // A task graph contains a unique set of tasks with edges between 113 // dependencies pointing in the direction of the dependents. Each task 114 // need to be assigned a unique priority and a run count that matches 115 // the number of dependencies. 116 typedef base::ScopedPtrHashMap<internal::WorkerPoolTask*, internal::GraphNode> 117 GraphNodeMap; 118 typedef GraphNodeMap TaskGraph; 119 120 WorkerPool(size_t num_threads, const std::string& thread_name_prefix); 121 122 // Schedule running of tasks in |graph|. Any previously scheduled tasks 123 // that are not already running will be canceled. Canceled tasks don't run 124 // but completion of them is still processed. 125 void SetTaskGraph(TaskGraph* graph); 126 127 private: 128 class Inner; 129 friend class Inner; 130 131 typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector; 132 133 void ProcessCompletedTasks(const TaskVector& completed_tasks); 134 135 bool in_dispatch_completion_callbacks_; 136 137 // Hide the gory details of the worker pool in |inner_|. 138 const scoped_ptr<Inner> inner_; 139 }; 140 141 } // namespace cc 142 143 #endif // CC_RESOURCES_WORKER_POOL_H_ 144