// std::thread per core.
bool UseHyperThreads = true;
+ // If set, will constrain 'ThreadsRequested' to the number of hardware
+ // threads, or hardware cores.
+ bool Limit = false;
+
/// Retrieves the max available threads for the current strategy. This
/// accounts for affinity masks and takes advantage of all CPU sockets.
unsigned compute_thread_count() const;
int computeHostNumHardwareThreads();
unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
- if (ThreadsRequested > 0)
- return ThreadsRequested;
-
int MaxThreadCount = UseHyperThreads ? computeHostNumHardwareThreads()
: sys::getHostNumPhysicalCores();
if (MaxThreadCount <= 0)
MaxThreadCount = 1;
- return MaxThreadCount;
+ if (ThreadsRequested == 0)
+ return MaxThreadCount;
+ if (!Limit)
+ return ThreadsRequested;
+ return std::min((unsigned)MaxThreadCount, ThreadsRequested);
}
namespace {
// Shared a single binary holder for all the link steps.
BinaryHolder BinHolder;
- unsigned ThreadCount = Options.LinkOpts.Threads;
- if (!ThreadCount)
- ThreadCount = DebugMapPtrsOrErr->size();
- ThreadPool Threads(hardware_concurrency(ThreadCount));
+ ThreadPoolStrategy S = hardware_concurrency(Options.LinkOpts.Threads);
+ if (Options.LinkOpts.Threads == 0) {
+ // If NumThreads is not specified, create one thread for each input, up to
+ // the number of hardware threads.
+ S.ThreadsRequested = DebugMapPtrsOrErr->size();
+ S.Limit = true;
+ }
+ ThreadPool Threads(S);
// If there is more than one link to execute, we need to generate
// temporary files.
// FIXME: The DwarfLinker can have some very deep recursion that can max
// out the (significantly smaller) stack when using threads. We don't
// want this limitation when we only have a single thread.
- if (ThreadCount == 1)
+ if (S.ThreadsRequested == 1)
LinkLambda(OS, Options.LinkOpts);
else
Threads.async(LinkLambda, OS, Options.LinkOpts);
(SourceFiles.size() != 1) || ViewOpts.hasOutputDirectory() ||
(ViewOpts.Format == CoverageViewOptions::OutputFormat::HTML);
- auto NumThreads = ViewOpts.NumThreads;
-
- // If NumThreads is not specified, auto-detect a good default.
- if (NumThreads == 0)
- NumThreads = SourceFiles.size();
+ ThreadPoolStrategy S = hardware_concurrency(ViewOpts.NumThreads);
+ if (ViewOpts.NumThreads == 0) {
+ // If NumThreads is not specified, create one thread for each input, up to
+ // the number of hardware cores.
+ S = heavyweight_hardware_concurrency(SourceFiles.size());
+ S.Limit = true;
+ }
- if (!ViewOpts.hasOutputDirectory() || NumThreads == 1) {
+ if (!ViewOpts.hasOutputDirectory() || S.ThreadsRequested == 1) {
for (const std::string &SourceFile : SourceFiles)
writeSourceFileView(SourceFile, Coverage.get(), Printer.get(),
ShowFilenames);
} else {
// In -output-dir mode, it's safe to use multiple threads to print files.
- ThreadPool Pool(heavyweight_hardware_concurrency(NumThreads));
+ ThreadPool Pool(S);
for (const std::string &SourceFile : SourceFiles)
Pool.async(&CodeCoverageTool::writeSourceFileView, this, SourceFile,
Coverage.get(), Printer.get(), ShowFilenames);
ArrayRef<std::string> SourceFiles,
ArrayRef<FileCoverageSummary> FileReports,
const CoverageViewOptions &Options) {
- auto NumThreads = Options.NumThreads;
- if (NumThreads == 0)
- NumThreads = SourceFiles.size();
- ThreadPool Pool(heavyweight_hardware_concurrency(NumThreads));
+ ThreadPoolStrategy S = hardware_concurrency(Options.NumThreads);
+ if (Options.NumThreads == 0) {
+ // If NumThreads is not specified, create one thread for each input, up to
+ // the number of hardware cores.
+ S = heavyweight_hardware_concurrency(SourceFiles.size());
+ S.Limit = true;
+ }
+ ThreadPool Pool(S);
json::Array FileArray;
std::mutex FileArrayMutex;
ArrayRef<std::string> Files, const CoverageViewOptions &Options,
const CoverageFilter &Filters) {
unsigned LCP = getRedundantPrefixLen(Files);
- auto NumThreads = Options.NumThreads;
- // If NumThreads is not specified, auto-detect a good default.
- if (NumThreads == 0)
- NumThreads = Files.size();
- ThreadPool Pool(heavyweight_hardware_concurrency(NumThreads));
+ ThreadPoolStrategy S = hardware_concurrency(Options.NumThreads);
+ if (Options.NumThreads == 0) {
+ // If NumThreads is not specified, create one thread for each input, up to
+ // the number of hardware cores.
+ S = heavyweight_hardware_concurrency(Files.size());
+ S.Limit = true;
+ }
+ ThreadPool Pool(S);
std::vector<FileCoverageSummary> FileReports;
FileReports.reserve(Files.size());