13#ifndef LLVM_SUPPORT_THREADPOOL_H
14#define LLVM_SUPPORT_THREADPOOL_H
18#include "llvm/Config/llvm-config.h"
27#include <condition_variable>
80 template <
typename Function,
typename... Args>
83 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
84 return async(std::move(Task));
88 template <
typename Function,
typename... Args>
91 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
92 return async(Group, std::move(Task));
97 template <
typename Func>
98 auto async(Func &&
F) -> std::shared_future<
decltype(
F())> {
103 template <
typename Func>
105 -> std::shared_future<
decltype(
F())> {
113 template <
typename ResTy>
116 auto Future = std::async(std::launch::deferred, std::move(Task)).share();
117 asyncEnqueue([Future]() { Future.wait(); }, Group);
122#if LLVM_ENABLE_THREADS
136 ~StdThreadPool()
override;
141 void wait()
override;
148 void wait(ThreadPoolTaskGroup &Group)
override;
152 unsigned getMaxConcurrency()
const override {
return MaxThreadCount; }
155 bool isWorkerThread()
const;
160 bool workCompletedUnlocked(ThreadPoolTaskGroup *Group)
const;
164 void asyncEnqueue(llvm::unique_function<
void()> Task,
165 ThreadPoolTaskGroup *Group)
override {
166 int requestedThreads;
169 std::unique_lock<std::mutex> LockGuard(QueueLock);
172 assert(EnableFlag &&
"Queuing a thread during ThreadPool destruction");
173 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
174 requestedThreads = ActiveThreads + Tasks.size();
176 QueueCondition.notify_one();
177 grow(requestedThreads);
182 void grow(
int requested);
184 void processTasks(ThreadPoolTaskGroup *WaitingForGroup);
185 void processTasksWithJobserver();
188 std::vector<llvm::thread> Threads;
193 std::deque<std::pair<llvm::unique_function<void()>, ThreadPoolTaskGroup *>>
197 std::mutex QueueLock;
198 std::condition_variable QueueCondition;
201 std::condition_variable CompletionCondition;
204 unsigned ActiveThreads = 0;
206 DenseMap<ThreadPoolTaskGroup *, unsigned> ActiveGroups;
209 bool EnableFlag =
true;
211 const ThreadPoolStrategy Strategy;
214 const unsigned MaxThreadCount;
216 JobserverClient *TheJobserver =
nullptr;
230 void wait()
override;
239 bool isWorkerThread()
const;
246 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
254#if LLVM_ENABLE_THREADS
274 template <
typename Function,
typename... Args>
276 return Pool.async(*
this, std::forward<Function>(
F),
277 std::forward<Args>(ArgList)...);
281 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.
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