]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Support/ThreadPool.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Support / ThreadPool.h
1 //===-- llvm/Support/ThreadPool.h - A ThreadPool implementation -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a crude C++11 based thread pool.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SUPPORT_THREAD_POOL_H
15 #define LLVM_SUPPORT_THREAD_POOL_H
16
17 #include "llvm/Config/llvm-config.h"
18 #include "llvm/Support/thread.h"
19
20 #include <future>
21
22 #include <atomic>
23 #include <condition_variable>
24 #include <functional>
25 #include <memory>
26 #include <mutex>
27 #include <queue>
28 #include <utility>
29
30 namespace llvm {
31
32 /// A ThreadPool for asynchronous parallel execution on a defined number of
33 /// threads.
34 ///
35 /// The pool keeps a vector of threads alive, waiting on a condition variable
36 /// for some work to become available.
37 class ThreadPool {
38 public:
39   using TaskTy = std::function<void()>;
40   using PackagedTaskTy = std::packaged_task<void()>;
41
42   /// Construct a pool with the number of threads found by
43   /// hardware_concurrency().
44   ThreadPool();
45
46   /// Construct a pool of \p ThreadCount threads
47   ThreadPool(unsigned ThreadCount);
48
49   /// Blocking destructor: the pool will wait for all the threads to complete.
50   ~ThreadPool();
51
52   /// Asynchronous submission of a task to the pool. The returned future can be
53   /// used to wait for the task to finish and is *non-blocking* on destruction.
54   template <typename Function, typename... Args>
55   inline std::shared_future<void> async(Function &&F, Args &&... ArgList) {
56     auto Task =
57         std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...);
58     return asyncImpl(std::move(Task));
59   }
60
61   /// Asynchronous submission of a task to the pool. The returned future can be
62   /// used to wait for the task to finish and is *non-blocking* on destruction.
63   template <typename Function>
64   inline std::shared_future<void> async(Function &&F) {
65     return asyncImpl(std::forward<Function>(F));
66   }
67
68   /// Blocking wait for all the threads to complete and the queue to be empty.
69   /// It is an error to try to add new tasks while blocking on this call.
70   void wait();
71
72 private:
73   /// Asynchronous submission of a task to the pool. The returned future can be
74   /// used to wait for the task to finish and is *non-blocking* on destruction.
75   std::shared_future<void> asyncImpl(TaskTy F);
76
77   /// Threads in flight
78   std::vector<llvm::thread> Threads;
79
80   /// Tasks waiting for execution in the pool.
81   std::queue<PackagedTaskTy> Tasks;
82
83   /// Locking and signaling for accessing the Tasks queue.
84   std::mutex QueueLock;
85   std::condition_variable QueueCondition;
86
87   /// Locking and signaling for job completion
88   std::mutex CompletionLock;
89   std::condition_variable CompletionCondition;
90
91   /// Keep track of the number of thread actually busy
92   std::atomic<unsigned> ActiveThreads;
93
94 #if LLVM_ENABLE_THREADS // avoids warning for unused variable
95   /// Signal for the destruction of the pool, asking thread to exit.
96   bool EnableFlag;
97 #endif
98 };
99 }
100
101 #endif // LLVM_SUPPORT_THREAD_POOL_H