1 //===- llvm/Support/Parallel.cpp - Parallel algorithms --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/Parallel.h"
11 #include "llvm/Config/llvm-config.h"
13 #if LLVM_ENABLE_THREADS
15 #include "llvm/Support/Threading.h"
25 /// An abstract class that takes closures and runs them asynchronously.
28 virtual ~Executor() = default;
29 virtual void add(std::function
<void()> func
) = 0;
31 static Executor
*getDefaultExecutor();
35 /// An Executor that runs tasks via ConcRT.
36 class ConcRTExecutor
: public Executor
{
38 Taskish(std::function
<void()> Task
) : Task(Task
) {}
40 std::function
<void()> Task
;
42 static void run(void *P
) {
43 Taskish
*Self
= static_cast<Taskish
*>(P
);
45 concurrency::Free(Self
);
50 virtual void add(std::function
<void()> F
) {
51 Concurrency::CurrentScheduler::ScheduleTask(
52 Taskish::run
, new (concurrency::Alloc(sizeof(Taskish
))) Taskish(F
));
56 Executor
*Executor::getDefaultExecutor() {
57 static ConcRTExecutor exec
;
62 /// An implementation of an Executor that runs closures on a thread pool
64 class ThreadPoolExecutor
: public Executor
{
66 explicit ThreadPoolExecutor(unsigned ThreadCount
= hardware_concurrency())
68 // Spawn all but one of the threads in another thread as spawning threads
70 std::thread([&, ThreadCount
] {
71 for (size_t i
= 1; i
< ThreadCount
; ++i
) {
72 std::thread([=] { work(); }).detach();
78 ~ThreadPoolExecutor() override
{
79 std::unique_lock
<std::mutex
> Lock(Mutex
);
86 void add(std::function
<void()> F
) override
{
87 std::unique_lock
<std::mutex
> Lock(Mutex
);
96 std::unique_lock
<std::mutex
> Lock(Mutex
);
97 Cond
.wait(Lock
, [&] { return Stop
|| !WorkStack
.empty(); });
100 auto Task
= WorkStack
.top();
108 std::atomic
<bool> Stop
{false};
109 std::stack
<std::function
<void()>> WorkStack
;
111 std::condition_variable Cond
;
112 parallel::detail::Latch Done
;
115 Executor
*Executor::getDefaultExecutor() {
116 static ThreadPoolExecutor exec
;
122 void parallel::detail::TaskGroup::spawn(std::function
<void()> F
) {
124 Executor::getDefaultExecutor()->add([&, F
] {
129 #endif // LLVM_ENABLE_THREADS