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