LLVM: include/llvm/Support/ThreadPool.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_SUPPORT_THREADPOOL_H
14#define LLVM_SUPPORT_THREADPOOL_H
15
18#include "llvm/Config/llvm-config.h"
24
25#include
26
27#include <condition_variable>
28#include
29#include
30#include
31#include
32
33namespace llvm {
34
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
52
53
56
57public:
58
59
61
62
63
64
66
67
68
69
70
71
73
74
76
77
78
79 template <typename Function, typename... Args>
81 auto Task =
82 std::bind(std::forward(F), std::forward(ArgList)...);
83 return async(std::move(Task));
84 }
85
86
87 template <typename Function, typename... Args>
89 auto Task =
90 std::bind(std::forward(F), std::forward(ArgList)...);
91 return async(Group, std::move(Task));
92 }
93
94
95
96 template
97 auto async(Func &&F) -> std::shared_future<decltype(F())> {
98 return asyncImpl(
100 }
101
102 template
104 -> std::shared_future<decltype(F())> {
105 return asyncImpl(
107 }
108
109private:
110
111
112 template
115 auto Future = std::async(std::launch::deferred, std::move(Task)).share();
116 asyncEnqueue([Future]() { Future.wait(); }, Group);
117 return Future;
118 }
119};
120
121#if LLVM_ENABLE_THREADS
122
123
124
125
127public:
128
129
130
131
133
134
135 ~StdThreadPool() override;
136
137
138
139
140 void wait() override;
141
142
143
144
145
146
147 void wait(ThreadPoolTaskGroup &Group) override;
148
149
150
151 unsigned getMaxConcurrency() const override { return MaxThreadCount; }
152
153
154 bool isWorkerThread() const;
155
156private:
157
158
159 bool workCompletedUnlocked(ThreadPoolTaskGroup *Group) const;
160
161
162
163 void asyncEnqueue(llvm::unique_function<void()> Task,
164 ThreadPoolTaskGroup *Group) override {
165 int requestedThreads;
166 {
167
168 std::unique_lockstd::mutex LockGuard(QueueLock);
169
170
171 assert(EnableFlag && "Queuing a thread during ThreadPool destruction");
172 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
173 requestedThreads = ActiveThreads + Tasks.size();
174 }
175 QueueCondition.notify_one();
176 grow(requestedThreads);
177 }
178
179
180
181 void grow(int requested);
182
183 void processTasks(ThreadPoolTaskGroup *WaitingForGroup);
184 void processTasksWithJobserver();
185
186
187 std::vectorllvm::thread Threads;
188
190
191
192 std::deque<std::pair<llvm::unique_function<void()>, ThreadPoolTaskGroup *>>
193 Tasks;
194
195
196 std::mutex QueueLock;
197 std::condition_variable QueueCondition;
198
199
200 std::condition_variable CompletionCondition;
201
202
203 unsigned ActiveThreads = 0;
204
205 DenseMap<ThreadPoolTaskGroup *, unsigned> ActiveGroups;
206
207
208 bool EnableFlag = true;
209
210 const ThreadPoolStrategy Strategy;
211
212
213 const unsigned MaxThreadCount;
214
215 JobserverClient *TheJobserver = nullptr;
216};
217#endif
218
219
221public:
222
224
225
227
228
229
230
233
234
235 void wait() override;
236
237
239
240
242
243
244 bool isWorkerThread() const;
245
246private:
247
248
251 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
252 }
253
254
256 Tasks;
257};
258
259#if LLVM_ENABLE_THREADS
261#else
263#endif
264
265
266
267
268
270public:
271
273
274
275
277
278
279 template <typename Function, typename... Args>
281 return Pool.async(*this, std::forward(F),
282 std::forward(ArgList)...);
283 }
284
285
286 void wait() { Pool.wait(*this); }
287
288private:
290};
291
292}
293
294#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
A non-threaded implementation.
Definition ThreadPool.h:220
SingleThreadExecutor(const SingleThreadExecutor &)=delete
SingleThreadExecutor(ThreadPoolStrategy ignored={})
Construct a non-threaded pool, ignoring using the hardware strategy.
void wait() override
Blocking wait for all the tasks to execute first.
SingleThreadExecutor & operator=(const SingleThreadExecutor &)=delete
unsigned getMaxConcurrency() const override
Returns always 1: there is no concurrency.
Definition ThreadPool.h:241
This defines the abstract base interface for a ThreadPool allowing asynchronous parallel execution on...
Definition ThreadPool.h:51
auto async(ThreadPoolTaskGroup &Group, Function &&F, Args &&...ArgList)
Overload, task will be in the given task group.
Definition ThreadPool.h:88
virtual void wait()=0
Blocking wait for all the threads to complete and the queue to be empty.
auto async(ThreadPoolTaskGroup &Group, Func &&F) -> std::shared_future< decltype(F())>
Definition ThreadPool.h:103
virtual unsigned getMaxConcurrency() const =0
Returns the maximum number of worker this pool can eventually grow to.
auto async(Func &&F) -> std::shared_future< decltype(F())>
Asynchronous submission of a task to the pool.
Definition ThreadPool.h:97
virtual ~ThreadPoolInterface()
Destroying the pool will drain the pending tasks and wait.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition ThreadPool.h:80
virtual void wait(ThreadPoolTaskGroup &Group)=0
Blocking wait for only all the threads in the given group to complete.
This tells how a thread pool will be used.
A group of tasks to be run on a thread pool.
Definition ThreadPool.h:269
auto async(Function &&F, Args &&...ArgList)
Calls ThreadPool::async() for this group.
Definition ThreadPool.h:280
void wait()
Calls ThreadPool::wait() for this group.
Definition ThreadPool.h:286
~ThreadPoolTaskGroup()
Blocking destructor: will wait for all the tasks in the group to complete by calling ThreadPool::wait...
Definition ThreadPool.h:276
ThreadPoolTaskGroup(ThreadPoolInterface &Pool)
The ThreadPool argument is the thread pool to forward calls to.
Definition ThreadPool.h:272
unique_function is a type-erasing functor similar to std::function.
SmartRWMutex< false > RWMutex
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
SingleThreadExecutor DefaultThreadPool
Definition ThreadPool.h:262