diff options
Diffstat (limited to 'lib/Support/Parallel.cpp')
-rw-r--r-- | lib/Support/Parallel.cpp | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/Support/Parallel.cpp b/lib/Support/Parallel.cpp index 1844003b9d3d..621bccbf2a4c 100644 --- a/lib/Support/Parallel.cpp +++ b/lib/Support/Parallel.cpp @@ -1,9 +1,8 @@ //===- llvm/Support/Parallel.cpp - Parallel algorithms --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -18,7 +17,9 @@ #include <stack> #include <thread> -using namespace llvm; +namespace llvm { +namespace parallel { +namespace detail { namespace { @@ -119,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 |