xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/Threading.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines helper functions for running LLVM in a multi-threaded
100b57cec5SDimitry Andric // environment.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/Support/Threading.h"
150b57cec5SDimitry Andric #include "llvm/Config/config.h"
16bdd1243dSDimitry Andric #include "llvm/Config/llvm-config.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include <cassert>
190b57cec5SDimitry Andric #include <errno.h>
20bdd1243dSDimitry Andric #include <optional>
210b57cec5SDimitry Andric #include <stdlib.h>
220b57cec5SDimitry Andric #include <string.h>
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
270b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
280b57cec5SDimitry Andric //===          independent code.
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #if LLVM_ENABLE_THREADS == 0 ||                                                \
320b57cec5SDimitry Andric     (!defined(_WIN32) && !defined(HAVE_PTHREAD_H))
get_threadid()330b57cec5SDimitry Andric uint64_t llvm::get_threadid() { return 0; }
340b57cec5SDimitry Andric 
get_max_thread_name_length()350b57cec5SDimitry Andric uint32_t llvm::get_max_thread_name_length() { return 0; }
360b57cec5SDimitry Andric 
set_thread_name(const Twine & Name)370b57cec5SDimitry Andric void llvm::set_thread_name(const Twine &Name) {}
380b57cec5SDimitry Andric 
get_thread_name(SmallVectorImpl<char> & Name)390b57cec5SDimitry Andric void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); }
400b57cec5SDimitry Andric 
get_thread_affinity_mask()415ffd83dbSDimitry Andric llvm::BitVector llvm::get_thread_affinity_mask() { return {}; }
425ffd83dbSDimitry Andric 
compute_thread_count() const435ffd83dbSDimitry Andric unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
445ffd83dbSDimitry Andric   // When threads are disabled, ensure clients will loop at least once.
455ffd83dbSDimitry Andric   return 1;
465ffd83dbSDimitry Andric }
475ffd83dbSDimitry Andric 
48bdd1243dSDimitry Andric // Unknown if threading turned off
get_physical_cores()49bdd1243dSDimitry Andric int llvm::get_physical_cores() { return -1; }
50bdd1243dSDimitry Andric 
510b57cec5SDimitry Andric #else
520b57cec5SDimitry Andric 
53bdd1243dSDimitry Andric static int computeHostNumHardwareThreads();
540b57cec5SDimitry Andric 
compute_thread_count() const555ffd83dbSDimitry Andric unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
56bdd1243dSDimitry Andric   int MaxThreadCount =
57bdd1243dSDimitry Andric       UseHyperThreads ? computeHostNumHardwareThreads() : get_physical_cores();
585ffd83dbSDimitry Andric   if (MaxThreadCount <= 0)
595ffd83dbSDimitry Andric     MaxThreadCount = 1;
6004bab189SMateusz Guzik   // Damage control threading.
6104bab189SMateusz Guzik   //
6204bab189SMateusz Guzik   // There are no heuristics to figure out how many threads makes sense to spawn,
6304bab189SMateusz Guzik   // all while rolling with all available hw threads starts being detrimental to
6404bab189SMateusz Guzik   // performance really early.
6504bab189SMateusz Guzik   //
6604bab189SMateusz Guzik   // Work around by putting a hard cap unless the user explicitly requested a certain amount.
6704bab189SMateusz Guzik   //
6804bab189SMateusz Guzik   // See https://discourse.llvm.org/t/avoidable-overhead-from-threading-by-default/69160
6904bab189SMateusz Guzik   // for more details.
7004bab189SMateusz Guzik   if (ThreadsRequested == 0) {
7104bab189SMateusz Guzik     return std::min(MaxThreadCount, 4);
7204bab189SMateusz Guzik   }
735ffd83dbSDimitry Andric   if (!Limit)
745ffd83dbSDimitry Andric     return ThreadsRequested;
755ffd83dbSDimitry Andric   return std::min((unsigned)MaxThreadCount, ThreadsRequested);
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric // Include the platform-specific parts of this class.
790b57cec5SDimitry Andric #ifdef LLVM_ON_UNIX
800b57cec5SDimitry Andric #include "Unix/Threading.inc"
810b57cec5SDimitry Andric #endif
820b57cec5SDimitry Andric #ifdef _WIN32
830b57cec5SDimitry Andric #include "Windows/Threading.inc"
840b57cec5SDimitry Andric #endif
850b57cec5SDimitry Andric 
86fe6060f1SDimitry Andric // Must be included after Threading.inc to provide definition for llvm::thread
87fe6060f1SDimitry Andric // because FreeBSD's condvar.h (included by user.h) misuses the "thread"
88fe6060f1SDimitry Andric // keyword.
89fe6060f1SDimitry Andric #include "llvm/Support/thread.h"
90480093f4SDimitry Andric 
91fe6060f1SDimitry Andric #if defined(__APPLE__)
92fe6060f1SDimitry Andric   // Darwin's default stack size for threads except the main one is only 512KB,
93fe6060f1SDimitry Andric   // which is not enough for some/many normal LLVM compilations. This implements
94fe6060f1SDimitry Andric   // the same interface as std::thread but requests the same stack size as the
95fe6060f1SDimitry Andric   // main thread (8MB) before creation.
96bdd1243dSDimitry Andric const std::optional<unsigned> llvm::thread::DefaultStackSize = 8 * 1024 * 1024;
97*06c3fb27SDimitry Andric #elif defined(_AIX)
98*06c3fb27SDimitry Andric   // On AIX, the default pthread stack size limit is ~192k for 64-bit programs.
99*06c3fb27SDimitry Andric   // This limit is easily reached when doing link-time thinLTO. AIX library
100*06c3fb27SDimitry Andric   // developers have used 4MB, so we'll do the same.
101*06c3fb27SDimitry Andric const std::optional<unsigned> llvm::thread::DefaultStackSize = 4 * 1024 * 1024;
102fe6060f1SDimitry Andric #else
103bdd1243dSDimitry Andric const std::optional<unsigned> llvm::thread::DefaultStackSize;
104fe6060f1SDimitry Andric #endif
105480093f4SDimitry Andric 
106480093f4SDimitry Andric 
1070b57cec5SDimitry Andric #endif
1085ffd83dbSDimitry Andric 
109bdd1243dSDimitry Andric std::optional<ThreadPoolStrategy>
get_threadpool_strategy(StringRef Num,ThreadPoolStrategy Default)1105ffd83dbSDimitry Andric llvm::get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default) {
1115ffd83dbSDimitry Andric   if (Num == "all")
1125ffd83dbSDimitry Andric     return llvm::hardware_concurrency();
1135ffd83dbSDimitry Andric   if (Num.empty())
1145ffd83dbSDimitry Andric     return Default;
1155ffd83dbSDimitry Andric   unsigned V;
1165ffd83dbSDimitry Andric   if (Num.getAsInteger(10, V))
117bdd1243dSDimitry Andric     return std::nullopt; // malformed 'Num' value
1185ffd83dbSDimitry Andric   if (V == 0)
1195ffd83dbSDimitry Andric     return Default;
1205ffd83dbSDimitry Andric 
1215ffd83dbSDimitry Andric   // Do not take the Default into account. This effectively disables
1225ffd83dbSDimitry Andric   // heavyweight_hardware_concurrency() if the user asks for any number of
1235ffd83dbSDimitry Andric   // threads on the cmd-line.
1245ffd83dbSDimitry Andric   ThreadPoolStrategy S = llvm::hardware_concurrency();
1255ffd83dbSDimitry Andric   S.ThreadsRequested = V;
1265ffd83dbSDimitry Andric   return S;
1275ffd83dbSDimitry Andric }
128