Files
llvm-project/llvm/lib/Support/Threading.cpp
Jessica Clarke f7361efc07 [Support] Avoid misguided FreeBSD hack (#177508)
FreeBSD doesn't do anything wrong here, it just happens to define and
use a struct thread in its own headers. The problems arise because here
in LLVM we have using namespace llvm prior to including system headers,
which is bad practice for precisely this reason. If we instead play by
the rules and defer our using namespace llvm until after we've included
the system headers then we no longer need this hack.

This hack is particularly problematic by being conditional on
__FreeBSD__ as of 9093ba9f7e ("[Support] Include Support/thread.h
before api implementations (#111175)"), since on non-FreeBSD
Threading.inc can reference anything in Support/thread.h, only causing
errors on FreeBSD, which is precisely what happened in 64be34c562
("Enable using threads on z/OS (#171847)").

By deferring the using namespace llvm until after Threading.inc is
included there may be build failures introduced on untested platforms
due to needing to replace unqualified identifiers with qualified ones by
prepending llvm::.
2026-01-23 18:48:20 +00:00

118 lines
3.7 KiB
C++

//===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines helper functions for running LLVM in a multi-threaded
// environment.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Threading.h"
#include "llvm/Config/config.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Jobserver.h"
#include <cassert>
#include <optional>
#include <stdlib.h>
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//=== independent code.
//===----------------------------------------------------------------------===//
#if LLVM_ENABLE_THREADS == 0 || \
(!defined(_WIN32) && !defined(HAVE_PTHREAD_H))
using namespace llvm;
uint64_t llvm::get_threadid() { return 0; }
uint32_t llvm::get_max_thread_name_length() { return 0; }
void llvm::set_thread_name(const Twine &Name) {}
void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); }
llvm::BitVector llvm::get_thread_affinity_mask() { return {}; }
unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
// When threads are disabled, ensure clients will loop at least once.
return 1;
}
// Unknown if threading turned off
int llvm::get_physical_cores() { return -1; }
#else
static int computeHostNumHardwareThreads();
// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
#include "Unix/Threading.inc"
#endif
#ifdef _WIN32
#include "Windows/Threading.inc"
#endif
using namespace llvm;
unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
if (UseJobserver)
if (auto JS = JobserverClient::getInstance())
return JS->getNumJobs();
int MaxThreadCount =
UseHyperThreads ? computeHostNumHardwareThreads() : get_physical_cores();
if (MaxThreadCount <= 0)
MaxThreadCount = 1;
if (ThreadsRequested == 0)
return MaxThreadCount;
if (!Limit)
return ThreadsRequested;
return std::min((unsigned)MaxThreadCount, ThreadsRequested);
}
#if defined(__APPLE__)
// Darwin's default stack size for threads except the main one is only 512KB,
// which is not enough for some/many normal LLVM compilations. This implements
// the same interface as std::thread but requests the same stack size as the
// main thread (8MB) before creation.
const std::optional<unsigned> llvm::thread::DefaultStackSize = 8 * 1024 * 1024;
#elif defined(_AIX)
// On AIX, the default pthread stack size limit is ~192k for 64-bit programs.
// This limit is easily reached when doing link-time thinLTO. AIX library
// developers have used 4MB, so we'll do the same.
const std::optional<unsigned> llvm::thread::DefaultStackSize = 4 * 1024 * 1024;
#else
const std::optional<unsigned> llvm::thread::DefaultStackSize;
#endif
#endif
std::optional<ThreadPoolStrategy>
llvm::get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default) {
if (Num == "all")
return llvm::hardware_concurrency();
if (Num.empty())
return Default;
unsigned V;
if (Num.getAsInteger(10, V))
return std::nullopt; // malformed 'Num' value
if (V == 0)
return Default;
// Do not take the Default into account. This effectively disables
// heavyweight_hardware_concurrency() if the user asks for any number of
// threads on the cmd-line.
ThreadPoolStrategy S = llvm::hardware_concurrency();
S.ThreadsRequested = V;
return S;
}