13#ifndef LLVM_SUPPORT_THREADPOOL_H
14#define LLVM_SUPPORT_THREADPOOL_H
17#include "llvm/Config/llvm-config.h"
26#include <condition_variable>
54 virtual void asyncEnqueue(std::function<
void()> Task,
79 template <
typename Function,
typename... Args>
82 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
83 return async(std::move(Task));
87 template <
typename Function,
typename... Args>
90 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
91 return async(Group, std::move(Task));
96 template <
typename Func>
97 auto async(Func &&
F) -> std::shared_future<
decltype(
F())> {
98 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
102 template <
typename Func>
104 -> std::shared_future<
decltype(
F())> {
105 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
112 template <
typename ResTy>
113 std::shared_future<ResTy> asyncImpl(std::function<ResTy()> Task,
115 auto Future = std::async(std::launch::deferred, std::move(Task)).share();
116 asyncEnqueue([Future]() { Future.wait(); }, Group);
121#if LLVM_ENABLE_THREADS
135 ~StdThreadPool()
override;
140 void wait()
override;
147 void wait(ThreadPoolTaskGroup &Group)
override;
151 unsigned getMaxConcurrency()
const override {
return MaxThreadCount; }
154 bool isWorkerThread()
const;
159 bool workCompletedUnlocked(ThreadPoolTaskGroup *Group)
const;
163 void asyncEnqueue(std::function<
void()> Task,
164 ThreadPoolTaskGroup *Group)
override {
165 int requestedThreads;
168 std::unique_lock<std::mutex> LockGuard(QueueLock);
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();
175 QueueCondition.notify_one();
176 grow(requestedThreads);
181 void grow(
int requested);
183 void processTasks(ThreadPoolTaskGroup *WaitingForGroup);
184 void processTasksWithJobserver();
187 std::vector<llvm::thread> Threads;
192 std::deque<std::pair<std::function<void()>, ThreadPoolTaskGroup *>> Tasks;
195 std::mutex QueueLock;
196 std::condition_variable QueueCondition;
199 std::condition_variable CompletionCondition;
202 unsigned ActiveThreads = 0;
204 DenseMap<ThreadPoolTaskGroup *, unsigned> ActiveGroups;
207 bool EnableFlag =
true;
209 const ThreadPoolStrategy Strategy;
212 const unsigned MaxThreadCount;
214 JobserverClient *TheJobserver =
nullptr;
228 void wait()
override;
237 bool isWorkerThread()
const;
242 void asyncEnqueue(std::function<
void()> Task,
244 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
248 std::deque<std::pair<std::function<void()>, ThreadPoolTaskGroup *>> Tasks;
251#if LLVM_ENABLE_THREADS
271 template <
typename Function,
typename... Args>
273 return Pool.async(*
this, std::forward<Function>(
F),
274 std::forward<Args>(ArgList)...);
278 void wait() { Pool.wait(*
this); }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
A non-threaded implementation.
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.
unsigned getMaxConcurrency() const override
Returns always 1: there is no concurrency.
This defines the abstract base interface for a ThreadPool allowing asynchronous parallel execution on...
auto async(ThreadPoolTaskGroup &Group, Function &&F, Args &&...ArgList)
Overload, task will be in the given task group.
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())>
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.
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.
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.
auto async(Function &&F, Args &&...ArgList)
Calls ThreadPool::async() for this group.
void wait()
Calls ThreadPool::wait() for this group.
~ThreadPoolTaskGroup()
Blocking destructor: will wait for all the tasks in the group to complete by calling ThreadPool::wait...
ThreadPoolTaskGroup(ThreadPoolInterface &Pool)
The ThreadPool argument is the thread pool to forward calls to.
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