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