13#ifndef LLVM_SUPPORT_THREADPOOL_H
14#define LLVM_SUPPORT_THREADPOOL_H
17#include "llvm/Config/llvm-config.h"
24#include <condition_variable>
33class ThreadPoolTaskGroup;
65 template <
typename Function,
typename... Args>
68 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
69 return async(std::move(Task));
73 template <
typename Function,
typename... Args>
76 std::bind(std::forward<Function>(
F), std::forward<Args>(ArgList)...);
77 return async(Group, std::move(Task));
82 template <
typename Func>
83 auto async(Func &&
F) -> std::shared_future<
decltype(
F())> {
84 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
88 template <
typename Func>
90 -> std::shared_future<
decltype(
F())> {
91 return asyncImpl(std::function<
decltype(
F())()>(std::forward<Func>(
F)),
119 template <
typename ResTy>
120 static std::pair<std::function<void()>, std::future<ResTy>>
121 createTaskAndFuture(std::function<ResTy()> Task) {
122 std::shared_ptr<std::promise<ResTy>> Promise =
123 std::make_shared<std::promise<ResTy>>();
124 auto F = Promise->get_future();
126 [Promise = std::move(Promise), Task]() { Promise->set_value(Task()); },
129 static std::pair<std::function<void()>, std::future<void>>
130 createTaskAndFuture(std::function<
void()> Task) {
131 std::shared_ptr<std::promise<void>> Promise =
132 std::make_shared<std::promise<void>>();
133 auto F = Promise->get_future();
134 return {[Promise = std::move(Promise), Task]() {
136 Promise->set_value();
143 bool workCompletedUnlocked(ThreadPoolTaskGroup *Group)
const;
147 template <
typename ResTy>
148 std::shared_future<ResTy> asyncImpl(std::function<ResTy()> Task,
149 ThreadPoolTaskGroup *Group) {
151#if LLVM_ENABLE_THREADS
154 auto R = createTaskAndFuture(Task);
156 int requestedThreads;
159 std::unique_lock<std::mutex> LockGuard(QueueLock);
162 assert(EnableFlag &&
"Queuing a thread during ThreadPool destruction");
163 Tasks.emplace_back(std::make_pair(std::move(
R.first), Group));
164 requestedThreads = ActiveThreads + Tasks.size();
166 QueueCondition.notify_one();
167 grow(requestedThreads);
168 return R.second.share();
173 auto Future = std::async(std::launch::deferred, std::move(Task)).share();
176 Tasks.emplace_back(std::make_pair([Future]() { Future.get(); }, Group));
181#if LLVM_ENABLE_THREADS
184 void grow(
int requested);
186 void processTasks(ThreadPoolTaskGroup *WaitingForGroup);
190 std::vector<llvm::thread> Threads;
195 std::deque<std::pair<std::function<void()>, ThreadPoolTaskGroup *>> Tasks;
198 std::mutex QueueLock;
199 std::condition_variable QueueCondition;
202 std::condition_variable CompletionCondition;
205 unsigned ActiveThreads = 0;
207 DenseMap<ThreadPoolTaskGroup *, unsigned> ActiveGroups;
209#if LLVM_ENABLE_THREADS
211 bool EnableFlag = true;
214 const ThreadPoolStrategy Strategy;
217 const unsigned MaxThreadCount;
234 template <
typename Function,
typename... Args>
236 return Pool.
async(*
this, std::forward<Function>(
F),
237 std::forward<Args>(ArgList)...);
This file defines the DenseMap class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
ThreadPoolTaskGroup(ThreadPool &Pool)
The ThreadPool argument is the thread pool to forward calls to.
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...
A ThreadPool for asynchronous parallel execution on a defined number of threads.
void wait()
Blocking wait for all the threads to complete and the queue to be empty.
~ThreadPool()
Blocking destructor: the pool will wait for all the threads to complete.
bool isWorkerThread() const
Returns true if the current thread is a worker thread of this thread pool.
unsigned getThreadCount() const
auto async(ThreadPoolTaskGroup &Group, Function &&F, Args &&...ArgList)
Overload, task will be in the given task group.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
auto async(Func &&F) -> std::shared_future< decltype(F())>
Asynchronous submission of a task to the pool.
auto async(ThreadPoolTaskGroup &Group, Func &&F) -> std::shared_future< decltype(F())>
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,...