diff options
-rw-r--r-- | llvm/include/llvm/Support/Parallel.h | 4 | ||||
-rw-r--r-- | llvm/lib/Support/Parallel.cpp | 31 |
2 files changed, 29 insertions, 6 deletions
diff --git a/llvm/include/llvm/Support/Parallel.h b/llvm/include/llvm/Support/Parallel.h index 9843b9518cd..eab9b492c4a 100644 --- a/llvm/include/llvm/Support/Parallel.h +++ b/llvm/include/llvm/Support/Parallel.h @@ -73,8 +73,12 @@ public: class TaskGroup { Latch L; + bool Parallel; public: + TaskGroup(); + ~TaskGroup(); + void spawn(std::function<void()> f); void sync() const { L.sync(); } diff --git a/llvm/lib/Support/Parallel.cpp b/llvm/lib/Support/Parallel.cpp index d40fce67e9a..621bccbf2a4 100644 --- a/llvm/lib/Support/Parallel.cpp +++ b/llvm/lib/Support/Parallel.cpp @@ -17,7 +17,9 @@ #include <stack> #include <thread> -using namespace llvm; +namespace llvm { +namespace parallel { +namespace detail { namespace { @@ -118,11 +120,28 @@ Executor *Executor::getDefaultExecutor() { #endif } -void parallel::detail::TaskGroup::spawn(std::function<void()> F) { - L.inc(); - Executor::getDefaultExecutor()->add([&, F] { +static std::atomic<int> TaskGroupInstances; + +// Latch::sync() called by the dtor may cause one thread to block. If is a dead +// lock if all threads in the default executor are blocked. To prevent the dead +// lock, only allow the first TaskGroup to run tasks parallelly. In the scenario +// of nested parallel_for_each(), only the outermost one runs parallelly. +TaskGroup::TaskGroup() : Parallel(TaskGroupInstances++ == 0) {} +TaskGroup::~TaskGroup() { --TaskGroupInstances; } + +void TaskGroup::spawn(std::function<void()> F) { + if (Parallel) { + L.inc(); + Executor::getDefaultExecutor()->add([&, F] { + F(); + L.dec(); + }); + } else { F(); - L.dec(); - }); + } } + +} // namespace detail +} // namespace parallel +} // namespace llvm #endif // LLVM_ENABLE_THREADS |