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/memory/ref_counted.h" 14#include "base/memory/scoped_ptr.h" 15#include "base/memory/weak_ptr.h" 16#include "base/message_loop/message_loop.h" 17#include "cc/base/cc_export.h" 18#include "cc/base/scoped_ptr_hash_map.h" 19 20namespace cc { 21namespace internal { 22 23class 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 50class 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) 87namespace BASE_HASH_NAMESPACE { 88template <> 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 96namespace cc { 97 98// A worker thread pool that runs tasks provided by task graph and 99// guarantees completion of all pending tasks at shutdown. 100class 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 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