10 #include "llvm/Config/llvm-config.h"
22 #if LLVM_ENABLE_THREADS
33 virtual ~Executor() =
default;
36 static Executor *getDefaultExecutor();
41 class ThreadPoolExecutor :
public Executor {
44 unsigned ThreadCount =
S.compute_thread_count();
47 Threads.reserve(ThreadCount);
50 Threads[0] = std::thread([
this, ThreadCount,
S] {
51 for (
unsigned I = 1;
I < ThreadCount; ++
I) {
52 Threads.emplace_back([=] { work(
S,
I); });
56 ThreadsCreated.set_value();
69 ThreadsCreated.get_future().wait();
72 ~ThreadPoolExecutor()
override {
75 for (std::thread &
T : Threads)
76 if (
T.get_id() == CurrentThreadId)
83 static void *
call() {
return new ThreadPoolExecutor(
strategy); }
86 static void call(
void *Ptr) { ((ThreadPoolExecutor *)Ptr)->stop(); }
99 S.apply_thread_strategy(ThreadID);
101 std::unique_lock<std::mutex>
Lock(
Mutex);
102 Cond.wait(
Lock, [&] {
return Stop || !WorkStack.empty(); });
112 std::atomic<bool> Stop{
false};
115 std::condition_variable
Cond;
116 std::promise<void> ThreadsCreated;
117 std::vector<std::thread> Threads;
120 Executor *Executor::getDefaultExecutor() {
139 static ManagedStatic<ThreadPoolExecutor, ThreadPoolExecutor::Creator,
140 ThreadPoolExecutor::Deleter>
142 static std::unique_ptr<ThreadPoolExecutor> Exec(&(*ManagedExec));
164 Executor::getDefaultExecutor()->add([&,
F =
std::move(
F)] {
176 #endif // LLVM_ENABLE_THREADS
184 #if LLVM_ENABLE_THREADS
185 auto NumItems = End - Begin;
194 for (; Begin + TaskSize < End; Begin += TaskSize) {
196 for (
size_t I = Begin,
E = Begin + TaskSize;
I !=
E; ++
I)
200 for (; Begin != End; ++Begin)
206 for (; Begin != End; ++Begin)