xref: /aosp_15_r20/external/angle/src/common/WorkerThread.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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