• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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