1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker // WorkerThread: 7*8975f5c5SAndroid Build Coastguard Worker // Asychronous tasks/threads for ANGLE, similar to a TaskRunner in Chromium. 8*8975f5c5SAndroid Build Coastguard Worker // Can be implemented as different targets, depending on platform. 9*8975f5c5SAndroid Build Coastguard Worker // 10*8975f5c5SAndroid Build Coastguard Worker 11*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_WORKER_THREAD_H_ 12*8975f5c5SAndroid Build Coastguard Worker #define COMMON_WORKER_THREAD_H_ 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker #include <array> 15*8975f5c5SAndroid Build Coastguard Worker #include <condition_variable> 16*8975f5c5SAndroid Build Coastguard Worker #include <memory> 17*8975f5c5SAndroid Build Coastguard Worker #include <mutex> 18*8975f5c5SAndroid Build Coastguard Worker #include <vector> 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h" 21*8975f5c5SAndroid Build Coastguard Worker #include "platform/PlatformMethods.h" 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker namespace angle 24*8975f5c5SAndroid Build Coastguard Worker { 25*8975f5c5SAndroid Build Coastguard Worker 26*8975f5c5SAndroid Build Coastguard Worker class WorkerThreadPool; 27*8975f5c5SAndroid Build Coastguard Worker 28*8975f5c5SAndroid Build Coastguard Worker // A callback function with no return value and no arguments. 29*8975f5c5SAndroid Build Coastguard Worker class Closure 30*8975f5c5SAndroid Build Coastguard Worker { 31*8975f5c5SAndroid Build Coastguard Worker public: 32*8975f5c5SAndroid Build Coastguard Worker virtual ~Closure() = default; 33*8975f5c5SAndroid Build Coastguard Worker virtual void operator()() = 0; 34*8975f5c5SAndroid Build Coastguard Worker }; 35*8975f5c5SAndroid Build Coastguard Worker 36*8975f5c5SAndroid Build Coastguard Worker // An event that we can wait on, useful for joining worker threads. 37*8975f5c5SAndroid Build Coastguard Worker class WaitableEvent : angle::NonCopyable 38*8975f5c5SAndroid Build Coastguard Worker { 39*8975f5c5SAndroid Build Coastguard Worker public: 40*8975f5c5SAndroid Build Coastguard Worker WaitableEvent(); 41*8975f5c5SAndroid Build Coastguard Worker virtual ~WaitableEvent(); 42*8975f5c5SAndroid Build Coastguard Worker 43*8975f5c5SAndroid Build Coastguard Worker // Waits indefinitely for the event to be signaled. 44*8975f5c5SAndroid Build Coastguard Worker virtual void wait() = 0; 45*8975f5c5SAndroid Build Coastguard Worker 46*8975f5c5SAndroid Build Coastguard Worker // Peeks whether the event is ready. If ready, wait() will not block. 47*8975f5c5SAndroid Build Coastguard Worker virtual bool isReady() = 0; 48*8975f5c5SAndroid Build Coastguard Worker 49*8975f5c5SAndroid Build Coastguard Worker template <class T> 50*8975f5c5SAndroid Build Coastguard Worker // Waits on multiple events. T should be some container of std::shared_ptr<WaitableEvent>. WaitMany(T * waitables)51*8975f5c5SAndroid Build Coastguard Worker static void WaitMany(T *waitables) 52*8975f5c5SAndroid Build Coastguard Worker { 53*8975f5c5SAndroid Build Coastguard Worker for (auto &waitable : *waitables) 54*8975f5c5SAndroid Build Coastguard Worker { 55*8975f5c5SAndroid Build Coastguard Worker waitable->wait(); 56*8975f5c5SAndroid Build Coastguard Worker } 57*8975f5c5SAndroid Build Coastguard Worker } 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker template <class T> 60*8975f5c5SAndroid Build Coastguard Worker // Checks if all events are ready. T should be some container of std::shared_ptr<WaitableEvent>. AllReady(T * waitables)61*8975f5c5SAndroid Build Coastguard Worker static bool AllReady(T *waitables) 62*8975f5c5SAndroid Build Coastguard Worker { 63*8975f5c5SAndroid Build Coastguard Worker for (auto &waitable : *waitables) 64*8975f5c5SAndroid Build Coastguard Worker { 65*8975f5c5SAndroid Build Coastguard Worker if (!waitable->isReady()) 66*8975f5c5SAndroid Build Coastguard Worker { 67*8975f5c5SAndroid Build Coastguard Worker return false; 68*8975f5c5SAndroid Build Coastguard Worker } 69*8975f5c5SAndroid Build Coastguard Worker } 70*8975f5c5SAndroid Build Coastguard Worker return true; 71*8975f5c5SAndroid Build Coastguard Worker } 72*8975f5c5SAndroid Build Coastguard Worker }; 73*8975f5c5SAndroid Build Coastguard Worker 74*8975f5c5SAndroid Build Coastguard Worker // A waitable event that is always ready. 75*8975f5c5SAndroid Build Coastguard Worker class WaitableEventDone final : public WaitableEvent 76*8975f5c5SAndroid Build Coastguard Worker { 77*8975f5c5SAndroid Build Coastguard Worker public: 78*8975f5c5SAndroid Build Coastguard Worker void wait() override; 79*8975f5c5SAndroid Build Coastguard Worker bool isReady() override; 80*8975f5c5SAndroid Build Coastguard Worker }; 81*8975f5c5SAndroid Build Coastguard Worker 82*8975f5c5SAndroid Build Coastguard Worker // A waitable event that can be completed asynchronously 83*8975f5c5SAndroid Build Coastguard Worker class AsyncWaitableEvent final : public WaitableEvent 84*8975f5c5SAndroid Build Coastguard Worker { 85*8975f5c5SAndroid Build Coastguard Worker public: 86*8975f5c5SAndroid Build Coastguard Worker AsyncWaitableEvent() = default; 87*8975f5c5SAndroid Build Coastguard Worker ~AsyncWaitableEvent() override = default; 88*8975f5c5SAndroid Build Coastguard Worker 89*8975f5c5SAndroid Build Coastguard Worker void wait() override; 90*8975f5c5SAndroid Build Coastguard Worker bool isReady() override; 91*8975f5c5SAndroid Build Coastguard Worker 92*8975f5c5SAndroid Build Coastguard Worker void markAsReady(); 93*8975f5c5SAndroid Build Coastguard Worker 94*8975f5c5SAndroid Build Coastguard Worker private: 95*8975f5c5SAndroid Build Coastguard Worker // To protect the concurrent accesses from both main thread and background 96*8975f5c5SAndroid Build Coastguard Worker // threads to the member fields. 97*8975f5c5SAndroid Build Coastguard Worker std::mutex mMutex; 98*8975f5c5SAndroid Build Coastguard Worker 99*8975f5c5SAndroid Build Coastguard Worker bool mIsReady = false; 100*8975f5c5SAndroid Build Coastguard Worker std::condition_variable mCondition; 101*8975f5c5SAndroid Build Coastguard Worker }; 102*8975f5c5SAndroid Build Coastguard Worker 103*8975f5c5SAndroid Build Coastguard Worker // Request WorkerThreads from the WorkerThreadPool. Each pool can keep worker threads around so 104*8975f5c5SAndroid Build Coastguard Worker // we avoid the costly spin up and spin down time. 105*8975f5c5SAndroid Build Coastguard Worker class WorkerThreadPool : angle::NonCopyable 106*8975f5c5SAndroid Build Coastguard Worker { 107*8975f5c5SAndroid Build Coastguard Worker public: 108*8975f5c5SAndroid Build Coastguard Worker WorkerThreadPool(); 109*8975f5c5SAndroid Build Coastguard Worker virtual ~WorkerThreadPool(); 110*8975f5c5SAndroid Build Coastguard Worker 111*8975f5c5SAndroid Build Coastguard Worker // Creates a new thread pool. 112*8975f5c5SAndroid Build Coastguard Worker // If numThreads is 0, the pool will choose the best number of threads to run. 113*8975f5c5SAndroid Build Coastguard Worker // If numThreads is 1, the pool will be single-threaded. Tasks will run on the calling thread. 114*8975f5c5SAndroid Build Coastguard Worker // Other numbers indicate how many threads the pool should spawn. 115*8975f5c5SAndroid Build Coastguard Worker // Note that based on build options, this class may not actually run tasks in threads, or it may 116*8975f5c5SAndroid Build Coastguard Worker // hook into the provided PlatformMethods::postWorkerTask, in which case numThreads is ignored. 117*8975f5c5SAndroid Build Coastguard Worker static std::shared_ptr<WorkerThreadPool> Create(size_t numThreads, PlatformMethods *platform); 118*8975f5c5SAndroid Build Coastguard Worker 119*8975f5c5SAndroid Build Coastguard Worker // Returns an event to wait on for the task to finish. If the pool fails to create the task, 120*8975f5c5SAndroid Build Coastguard Worker // returns null. This function is thread-safe. 121*8975f5c5SAndroid Build Coastguard Worker virtual std::shared_ptr<WaitableEvent> postWorkerTask(const std::shared_ptr<Closure> &task) = 0; 122*8975f5c5SAndroid Build Coastguard Worker 123*8975f5c5SAndroid Build Coastguard Worker virtual bool isAsync() = 0; 124*8975f5c5SAndroid Build Coastguard Worker 125*8975f5c5SAndroid Build Coastguard Worker private: 126*8975f5c5SAndroid Build Coastguard Worker }; 127*8975f5c5SAndroid Build Coastguard Worker 128*8975f5c5SAndroid Build Coastguard Worker } // namespace angle 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard Worker #endif // COMMON_WORKER_THREAD_H_ 131