diff --git a/lld/Common/Threads.cpp b/lld/Common/Threads.cpp --- a/lld/Common/Threads.cpp +++ b/lld/Common/Threads.cpp @@ -7,5 +7,7 @@ //===----------------------------------------------------------------------===// #include "lld/Common/Threads.h" +#include bool lld::ThreadsEnabled = true; +thread_local bool lld::ParallelForEachRunning; diff --git a/lld/include/lld/Common/Threads.h b/lld/include/lld/Common/Threads.h --- a/lld/include/lld/Common/Threads.h +++ b/lld/include/lld/Common/Threads.h @@ -64,20 +64,32 @@ namespace lld { extern bool ThreadsEnabled; +extern thread_local bool ParallelForEachRunning; template void parallelForEach(R &&Range, FuncTy Fn) { + // for_each is not reentrant, so guard against it. + assert(!ParallelForEachRunning); + ParallelForEachRunning = true; + if (ThreadsEnabled) for_each(llvm::parallel::par, std::begin(Range), std::end(Range), Fn); else for_each(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn); + + ParallelForEachRunning = false; } inline void parallelForEachN(size_t Begin, size_t End, llvm::function_ref Fn) { + assert(!ParallelForEachRunning); + ParallelForEachRunning = true; + if (ThreadsEnabled) for_each_n(llvm::parallel::par, Begin, End, Fn); else for_each_n(llvm::parallel::seq, Begin, End, Fn); + + ParallelForEachRunning = false; } template void parallelSort(R &&Range, FuncTy Fn) {