13#ifndef LLVM_SUPPORT_THREADPOOL_H
14#define LLVM_SUPPORT_THREADPOOL_H
17#include "llvm/Config/llvm-config.h"
25#include <condition_variable>
53 virtual void asyncEnqueue(std::function<
void()> Task,
78 template <
typename Function,
typename... Args>
81 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
82 return async(std::move(Task));
86 template <
typename Function,
typename... Args>
89 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
90 return async(Group, std::move(Task));
95 template <
typename Func>
96 auto async(Func &&
F) -> std::shared_future<
decltype(
F())> {
97 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
101 template <
typename Func>
103 -> std::shared_future<
decltype(
F())> {
104 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
111 template <
typename ResTy>
112 std::shared_future<ResTy> asyncImpl(std::function<ResTy()> Task,
114 auto Future = std::async(std::launch::deferred, std::move(Task)).share();
115 asyncEnqueue([Future]() { Future.wait(); }, Group);
120#if LLVM_ENABLE_THREADS
134 ~StdThreadPool()
override;
139 void wait()
override;
146 void wait(ThreadPoolTaskGroup &Group)
override;
150 unsigned getMaxConcurrency()
const override {
return MaxThreadCount; }
153 bool isWorkerThread()
const;
158 bool workCompletedUnlocked(ThreadPoolTaskGroup *Group)
const;
162 void asyncEnqueue(std::function<
void()> Task,
163 ThreadPoolTaskGroup *Group)
override {
164 int requestedThreads;
167 std::unique_lock<std::mutex> LockGuard(QueueLock);
170 assert(EnableFlag &&
"Queuing a thread during ThreadPool destruction");
171 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
172 requestedThreads = ActiveThreads + Tasks.size();
174 QueueCondition.notify_one();
175 grow(requestedThreads);
180 void grow(
int requested);
182 void processTasks(ThreadPoolTaskGroup *WaitingForGroup);
185 std::vector<llvm::thread> Threads;
190 std::deque<std::pair<std::function<void()>, ThreadPoolTaskGroup *>> Tasks;
193 std::mutex QueueLock;
194 std::condition_variable QueueCondition;
197 std::condition_variable CompletionCondition;
200 unsigned ActiveThreads = 0;
202 DenseMap<ThreadPoolTaskGroup *, unsigned> ActiveGroups;
205 bool EnableFlag =
true;
207 const ThreadPoolStrategy Strategy;
210 const unsigned MaxThreadCount;
224 void wait()
override;
233 bool isWorkerThread()
const;
238 void asyncEnqueue(std::function<
void()> Task,
240 Tasks.emplace_back(std::make_pair(std::move(Task), Group));
244 std::deque<std::pair<std::function<void()>, ThreadPoolTaskGroup *>> Tasks;
247#if LLVM_ENABLE_THREADS
267 template <
typename Function,
typename... Args>
269 return Pool.async(*
this, std::forward<Function>(
F),
270 std::forward<Args>(ArgList)...);
274 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