1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_THREAD_POOL_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_THREAD_POOL_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <deque> 21*795d594fSAndroid Build Coastguard Worker #include <functional> 22*795d594fSAndroid Build Coastguard Worker #include <vector> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include "barrier.h" 25*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 26*795d594fSAndroid Build Coastguard Worker #include "base/mem_map.h" 27*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h" 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker class AbstractThreadPool; 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker class Closure { 34*795d594fSAndroid Build Coastguard Worker public: ~Closure()35*795d594fSAndroid Build Coastguard Worker virtual ~Closure() { } 36*795d594fSAndroid Build Coastguard Worker virtual void Run(Thread* self) = 0; 37*795d594fSAndroid Build Coastguard Worker }; 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker class FunctionClosure : public Closure { 40*795d594fSAndroid Build Coastguard Worker public: FunctionClosure(std::function<void (Thread *)> && f)41*795d594fSAndroid Build Coastguard Worker explicit FunctionClosure(std::function<void(Thread*)>&& f) : func_(std::move(f)) {} Run(Thread * self)42*795d594fSAndroid Build Coastguard Worker void Run(Thread* self) override { 43*795d594fSAndroid Build Coastguard Worker func_(self); 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker private: 47*795d594fSAndroid Build Coastguard Worker std::function<void(Thread*)> func_; 48*795d594fSAndroid Build Coastguard Worker }; 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker class Task : public Closure { 51*795d594fSAndroid Build Coastguard Worker public: 52*795d594fSAndroid Build Coastguard Worker // Called after Closure::Run has been called. Finalize()53*795d594fSAndroid Build Coastguard Worker virtual void Finalize() { } 54*795d594fSAndroid Build Coastguard Worker }; 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker class SelfDeletingTask : public Task { 57*795d594fSAndroid Build Coastguard Worker public: ~SelfDeletingTask()58*795d594fSAndroid Build Coastguard Worker virtual ~SelfDeletingTask() { } Finalize()59*795d594fSAndroid Build Coastguard Worker virtual void Finalize() { 60*795d594fSAndroid Build Coastguard Worker delete this; 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker }; 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker class FunctionTask : public SelfDeletingTask { 65*795d594fSAndroid Build Coastguard Worker public: FunctionTask(std::function<void (Thread *)> && func)66*795d594fSAndroid Build Coastguard Worker explicit FunctionTask(std::function<void(Thread*)>&& func) : func_(std::move(func)) {} 67*795d594fSAndroid Build Coastguard Worker Run(Thread * self)68*795d594fSAndroid Build Coastguard Worker void Run(Thread* self) override { 69*795d594fSAndroid Build Coastguard Worker func_(self); 70*795d594fSAndroid Build Coastguard Worker } 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker private: 73*795d594fSAndroid Build Coastguard Worker std::function<void(Thread*)> func_; 74*795d594fSAndroid Build Coastguard Worker }; 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker class ThreadPoolWorker { 77*795d594fSAndroid Build Coastguard Worker public: 78*795d594fSAndroid Build Coastguard Worker static const size_t kDefaultStackSize = 1 * MB; 79*795d594fSAndroid Build Coastguard Worker GetStackSize()80*795d594fSAndroid Build Coastguard Worker size_t GetStackSize() const { 81*795d594fSAndroid Build Coastguard Worker DCHECK(stack_.IsValid()); 82*795d594fSAndroid Build Coastguard Worker return stack_.Size(); 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker virtual ~ThreadPoolWorker(); 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // Set the "nice" priority for this worker. 88*795d594fSAndroid Build Coastguard Worker void SetPthreadPriority(int priority); 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker // Get the "nice" priority for this worker. 91*795d594fSAndroid Build Coastguard Worker int GetPthreadPriority(); 92*795d594fSAndroid Build Coastguard Worker GetThread()93*795d594fSAndroid Build Coastguard Worker Thread* GetThread() const { return thread_; } 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker protected: 96*795d594fSAndroid Build Coastguard Worker ThreadPoolWorker(AbstractThreadPool* thread_pool, const std::string& name, size_t stack_size); 97*795d594fSAndroid Build Coastguard Worker static void* Callback(void* arg) REQUIRES(!Locks::mutator_lock_); 98*795d594fSAndroid Build Coastguard Worker virtual void Run(); 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker AbstractThreadPool* const thread_pool_; 101*795d594fSAndroid Build Coastguard Worker const std::string name_; 102*795d594fSAndroid Build Coastguard Worker MemMap stack_; 103*795d594fSAndroid Build Coastguard Worker pthread_t pthread_; 104*795d594fSAndroid Build Coastguard Worker Thread* thread_; 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker private: 107*795d594fSAndroid Build Coastguard Worker friend class AbstractThreadPool; 108*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ThreadPoolWorker); 109*795d594fSAndroid Build Coastguard Worker }; 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker // Note that thread pool workers will set Thread#setCanCallIntoJava to false. 112*795d594fSAndroid Build Coastguard Worker class AbstractThreadPool { 113*795d594fSAndroid Build Coastguard Worker public: 114*795d594fSAndroid Build Coastguard Worker // Returns the number of threads in the thread pool. GetThreadCount()115*795d594fSAndroid Build Coastguard Worker size_t GetThreadCount() const { 116*795d594fSAndroid Build Coastguard Worker return threads_.size(); 117*795d594fSAndroid Build Coastguard Worker } 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker EXPORT const std::vector<ThreadPoolWorker*>& GetWorkers(); 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker // Broadcast to the workers and tell them to empty out the work queue. 122*795d594fSAndroid Build Coastguard Worker EXPORT void StartWorkers(Thread* self) REQUIRES(!task_queue_lock_); 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker // Do not allow workers to grab any new tasks. 125*795d594fSAndroid Build Coastguard Worker EXPORT void StopWorkers(Thread* self) REQUIRES(!task_queue_lock_); 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker // Returns if the thread pool has started. 128*795d594fSAndroid Build Coastguard Worker bool HasStarted(Thread* self) REQUIRES(!task_queue_lock_); 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // Add a new task, the first available started worker will process it. Does not delete the task 131*795d594fSAndroid Build Coastguard Worker // after running it, it is the caller's responsibility. 132*795d594fSAndroid Build Coastguard Worker virtual void AddTask(Thread* self, Task* task) REQUIRES(!task_queue_lock_) = 0; 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker // Remove all tasks in the queue. 135*795d594fSAndroid Build Coastguard Worker virtual void RemoveAllTasks(Thread* self) REQUIRES(!task_queue_lock_) = 0; 136*795d594fSAndroid Build Coastguard Worker 137*795d594fSAndroid Build Coastguard Worker virtual size_t GetTaskCount(Thread* self) REQUIRES(!task_queue_lock_) = 0; 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker // Create the threads of this pool. 140*795d594fSAndroid Build Coastguard Worker EXPORT void CreateThreads(); 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker // Stops and deletes all threads in this pool. 143*795d594fSAndroid Build Coastguard Worker void DeleteThreads(); 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker // Wait for all tasks currently on queue to get completed. If the pool has been stopped, only 146*795d594fSAndroid Build Coastguard Worker // wait till all already running tasks are done. 147*795d594fSAndroid Build Coastguard Worker // When the pool was created with peers for workers, do_work must not be true (see ThreadPool()). 148*795d594fSAndroid Build Coastguard Worker EXPORT void Wait(Thread* self, bool do_work, bool may_hold_locks) REQUIRES(!task_queue_lock_); 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // Returns the total amount of workers waited for tasks. GetWaitTime()151*795d594fSAndroid Build Coastguard Worker uint64_t GetWaitTime() const { 152*795d594fSAndroid Build Coastguard Worker return total_wait_time_; 153*795d594fSAndroid Build Coastguard Worker } 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker // Provides a way to bound the maximum number of worker threads, threads must be less the the 156*795d594fSAndroid Build Coastguard Worker // thread count of the thread pool. 157*795d594fSAndroid Build Coastguard Worker void SetMaxActiveWorkers(size_t threads) REQUIRES(!task_queue_lock_); 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker // Set the "nice" priority for threads in the pool. 160*795d594fSAndroid Build Coastguard Worker void SetPthreadPriority(int priority); 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker // CHECK that the "nice" priority of threads in the pool is the given 163*795d594fSAndroid Build Coastguard Worker // `priority`. 164*795d594fSAndroid Build Coastguard Worker void CheckPthreadPriority(int priority); 165*795d594fSAndroid Build Coastguard Worker 166*795d594fSAndroid Build Coastguard Worker // Wait for workers to be created. 167*795d594fSAndroid Build Coastguard Worker void WaitForWorkersToBeCreated(); 168*795d594fSAndroid Build Coastguard Worker ~AbstractThreadPool()169*795d594fSAndroid Build Coastguard Worker virtual ~AbstractThreadPool() {} 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker protected: 172*795d594fSAndroid Build Coastguard Worker // get a task to run, blocks if there are no tasks left 173*795d594fSAndroid Build Coastguard Worker Task* GetTask(Thread* self) REQUIRES(!task_queue_lock_); 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker // Try to get a task, returning null if there is none available. 176*795d594fSAndroid Build Coastguard Worker Task* TryGetTask(Thread* self) REQUIRES(!task_queue_lock_); 177*795d594fSAndroid Build Coastguard Worker virtual Task* TryGetTaskLocked() REQUIRES(task_queue_lock_) = 0; 178*795d594fSAndroid Build Coastguard Worker 179*795d594fSAndroid Build Coastguard Worker // Are we shutting down? IsShuttingDown()180*795d594fSAndroid Build Coastguard Worker bool IsShuttingDown() const REQUIRES(task_queue_lock_) { 181*795d594fSAndroid Build Coastguard Worker return shutting_down_; 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker virtual bool HasOutstandingTasks() const REQUIRES(task_queue_lock_) = 0; 185*795d594fSAndroid Build Coastguard Worker 186*795d594fSAndroid Build Coastguard Worker EXPORT AbstractThreadPool(const char* name, 187*795d594fSAndroid Build Coastguard Worker size_t num_threads, 188*795d594fSAndroid Build Coastguard Worker bool create_peers, 189*795d594fSAndroid Build Coastguard Worker size_t worker_stack_size); 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker const std::string name_; 192*795d594fSAndroid Build Coastguard Worker Mutex task_queue_lock_; 193*795d594fSAndroid Build Coastguard Worker ConditionVariable task_queue_condition_ GUARDED_BY(task_queue_lock_); 194*795d594fSAndroid Build Coastguard Worker ConditionVariable completion_condition_ GUARDED_BY(task_queue_lock_); 195*795d594fSAndroid Build Coastguard Worker bool started_ GUARDED_BY(task_queue_lock_); 196*795d594fSAndroid Build Coastguard Worker bool shutting_down_ GUARDED_BY(task_queue_lock_); 197*795d594fSAndroid Build Coastguard Worker // How many worker threads are waiting on the condition. 198*795d594fSAndroid Build Coastguard Worker size_t waiting_count_ GUARDED_BY(task_queue_lock_); 199*795d594fSAndroid Build Coastguard Worker std::vector<ThreadPoolWorker*> threads_; 200*795d594fSAndroid Build Coastguard Worker // Work balance detection. 201*795d594fSAndroid Build Coastguard Worker uint64_t start_time_ GUARDED_BY(task_queue_lock_); 202*795d594fSAndroid Build Coastguard Worker uint64_t total_wait_time_; 203*795d594fSAndroid Build Coastguard Worker Barrier creation_barier_; 204*795d594fSAndroid Build Coastguard Worker size_t max_active_workers_ GUARDED_BY(task_queue_lock_); 205*795d594fSAndroid Build Coastguard Worker const bool create_peers_; 206*795d594fSAndroid Build Coastguard Worker const size_t worker_stack_size_; 207*795d594fSAndroid Build Coastguard Worker 208*795d594fSAndroid Build Coastguard Worker private: 209*795d594fSAndroid Build Coastguard Worker friend class ThreadPoolWorker; 210*795d594fSAndroid Build Coastguard Worker friend class WorkStealingWorker; 211*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(AbstractThreadPool); 212*795d594fSAndroid Build Coastguard Worker }; 213*795d594fSAndroid Build Coastguard Worker 214*795d594fSAndroid Build Coastguard Worker class EXPORT ThreadPool : public AbstractThreadPool { 215*795d594fSAndroid Build Coastguard Worker public: 216*795d594fSAndroid Build Coastguard Worker // Create a named thread pool with the given number of threads. 217*795d594fSAndroid Build Coastguard Worker // 218*795d594fSAndroid Build Coastguard Worker // If create_peers is true, all worker threads will have a Java peer object. Note that if the 219*795d594fSAndroid Build Coastguard Worker // pool is asked to do work on the current thread (see Wait), a peer may not be available. Wait 220*795d594fSAndroid Build Coastguard Worker // will conservatively abort if create_peers and do_work are true. 221*795d594fSAndroid Build Coastguard Worker static ThreadPool* Create(const char* name, 222*795d594fSAndroid Build Coastguard Worker size_t num_threads, 223*795d594fSAndroid Build Coastguard Worker bool create_peers = false, 224*795d594fSAndroid Build Coastguard Worker size_t worker_stack_size = ThreadPoolWorker::kDefaultStackSize) { 225*795d594fSAndroid Build Coastguard Worker ThreadPool* pool = new ThreadPool(name, num_threads, create_peers, worker_stack_size); 226*795d594fSAndroid Build Coastguard Worker pool->CreateThreads(); 227*795d594fSAndroid Build Coastguard Worker return pool; 228*795d594fSAndroid Build Coastguard Worker } 229*795d594fSAndroid Build Coastguard Worker 230*795d594fSAndroid Build Coastguard Worker void AddTask(Thread* self, Task* task) REQUIRES(!task_queue_lock_) override; 231*795d594fSAndroid Build Coastguard Worker size_t GetTaskCount(Thread* self) REQUIRES(!task_queue_lock_) override; 232*795d594fSAndroid Build Coastguard Worker void RemoveAllTasks(Thread* self) REQUIRES(!task_queue_lock_) override; 233*795d594fSAndroid Build Coastguard Worker ~ThreadPool() override; 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker protected: 236*795d594fSAndroid Build Coastguard Worker Task* TryGetTaskLocked() REQUIRES(task_queue_lock_) override; 237*795d594fSAndroid Build Coastguard Worker HasOutstandingTasks()238*795d594fSAndroid Build Coastguard Worker bool HasOutstandingTasks() const REQUIRES(task_queue_lock_) override { 239*795d594fSAndroid Build Coastguard Worker return started_ && !tasks_.empty(); 240*795d594fSAndroid Build Coastguard Worker } 241*795d594fSAndroid Build Coastguard Worker ThreadPool(const char * name,size_t num_threads,bool create_peers,size_t worker_stack_size)242*795d594fSAndroid Build Coastguard Worker ThreadPool(const char* name, 243*795d594fSAndroid Build Coastguard Worker size_t num_threads, 244*795d594fSAndroid Build Coastguard Worker bool create_peers, 245*795d594fSAndroid Build Coastguard Worker size_t worker_stack_size) 246*795d594fSAndroid Build Coastguard Worker : AbstractThreadPool(name, num_threads, create_peers, worker_stack_size) {} 247*795d594fSAndroid Build Coastguard Worker 248*795d594fSAndroid Build Coastguard Worker private: 249*795d594fSAndroid Build Coastguard Worker std::deque<Task*> tasks_ GUARDED_BY(task_queue_lock_); 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ThreadPool); 252*795d594fSAndroid Build Coastguard Worker }; 253*795d594fSAndroid Build Coastguard Worker 254*795d594fSAndroid Build Coastguard Worker } // namespace art 255*795d594fSAndroid Build Coastguard Worker 256*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_THREAD_POOL_H_ 257