23#include <mach/mach_init.h>
24#include <mach/mach_port.h>
25#include <pthread/qos.h>
26#include <sys/sysctl.h>
32#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
33#include <pthread_np.h>
38#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
40#include <sys/cpuset.h>
41#include <sys/sysctl.h>
46#if defined(__NetBSD__)
50#if defined(__OpenBSD__)
56#include <sys/syscall.h>
60#if defined(__CYGWIN__)
61#include <sys/cpuset.h>
70llvm_execute_on_thread_impl(
void *(*ThreadFunc)(
void *),
void *Arg,
71 std::optional<unsigned> StackSizeInBytes) {
76 if ((errnum = ::pthread_attr_init(&Attr)) != 0) {
81 if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) {
87 if (StackSizeInBytes) {
88 if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) {
95 if ((errnum = ::pthread_create(&Thread, &Attr, ThreadFunc, Arg)) != 0)
101void llvm_thread_detach_impl(pthread_t Thread) {
104 if ((errnum = ::pthread_detach(Thread)) != 0) {
109void llvm_thread_join_impl(pthread_t Thread) {
112 if ((errnum = ::pthread_join(Thread,
nullptr)) != 0) {
117llvm::thread::id llvm_thread_get_id_impl(pthread_t Thread) {
118#if defined(__LLVM_LIBC__)
121 if ((errnum = ::pthread_getunique_np(&Thread, &Id)) != 0) {
125#elif defined(__MVS__)
132llvm::thread::id llvm_thread_get_current_id_impl() {
133#if defined(__LLVM_LIBC__)
134 return ::pthread_getthreadid_np();
136 return llvm_thread_get_id_impl(::pthread_self());
143#if defined(__APPLE__)
147 static thread_local thread_port_t Self = [] {
148 thread_port_t InitSelf = mach_thread_self();
149 mach_port_deallocate(mach_task_self(), Self);
153#elif defined(__FreeBSD__) || defined(__DragonFly__)
154 return uint64_t(pthread_getthreadid_np());
155#elif defined(__NetBSD__)
157#elif defined(__OpenBSD__)
159#elif defined(__ANDROID__)
161#elif defined(__linux__)
162 return uint64_t(syscall(__NR_gettid));
165#elif defined(__MVS__)
166 return llvm_thread_get_id_impl(pthread_self());
172static constexpr uint32_t get_max_thread_name_length_impl() {
173#if defined(PTHREAD_MAX_NAMELEN_NP)
174 return PTHREAD_MAX_NAMELEN_NP;
175#elif defined(__HAIKU__)
176 return B_OS_NAME_LENGTH;
177#elif defined(__APPLE__)
179#elif defined(__sun__) && defined(__svr4__)
181#elif defined(__linux__) && HAVE_PTHREAD_SETNAME_NP
183#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
184 defined(__DragonFly__)
186#elif defined(__OpenBSD__)
188#elif defined(__CYGWIN__)
196 return get_max_thread_name_length_impl();
201 SmallString<64> Storage;
202 StringRef NameStr =
Name.toNullTerminatedStringRef(Storage);
213#if defined(HAVE_PTHREAD_SET_NAME_NP) && HAVE_PTHREAD_SET_NAME_NP
214 ::pthread_set_name_np(::pthread_self(), NameStr.data());
215#elif defined(HAVE_PTHREAD_SETNAME_NP) && HAVE_PTHREAD_SETNAME_NP
216#if defined(__NetBSD__)
217 ::pthread_setname_np(::pthread_self(),
"%s",
218 const_cast<char *
>(NameStr.data()));
219#elif defined(__APPLE__)
220 ::pthread_setname_np(NameStr.data());
222 ::pthread_setname_np(::pthread_self(), NameStr.data());
230#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
231 int pid = ::getpid();
234 struct kinfo_proc *kp =
nullptr, *nkp;
237 int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
241 error = sysctl(ctl, 4, kp, &len,
nullptr, 0);
242 if (kp ==
nullptr || (
error != 0 && errno == ENOMEM)) {
244 len +=
sizeof(*kp) + len / 10;
245 nkp = (
struct kinfo_proc *)::realloc(kp, len);
246 if (nkp ==
nullptr) {
258 for (
size_t i = 0; i < len /
sizeof(*kp); i++) {
259 if (kp[i].ki_tid == (lwpid_t)tid) {
260 Name.append(kp[i].ki_tdname, kp[i].ki_tdname + strlen(kp[i].ki_tdname));
266#elif (defined(__linux__) || defined(__CYGWIN__)) && HAVE_PTHREAD_GETNAME_NP
267 constexpr uint32_t len = get_max_thread_name_length_impl();
268 char Buffer[len] = {
'\0'};
269 if (0 == ::pthread_getname_np(::pthread_self(), Buffer, len))
270 Name.append(Buffer, Buffer + strlen(Buffer));
271#elif defined(HAVE_PTHREAD_GET_NAME_NP) && HAVE_PTHREAD_GET_NAME_NP
272 constexpr uint32_t len = get_max_thread_name_length_impl();
274 ::pthread_get_name_np(::pthread_self(), buf, len);
276 Name.append(buf, buf + strlen(buf));
278#elif defined(HAVE_PTHREAD_GETNAME_NP) && HAVE_PTHREAD_GETNAME_NP
279 constexpr uint32_t len = get_max_thread_name_length_impl();
281 ::pthread_getname_np(::pthread_self(), buf, len);
283 Name.append(buf, buf + strlen(buf));
289#if (defined(__linux__) || defined(__CYGWIN__)) && defined(SCHED_IDLE)
293 sched_param priority;
295 priority.sched_priority = 0;
298 return !pthread_setschedparam(
301 Priority == ThreadPriority::Default ? SCHED_OTHER : SCHED_IDLE,
303 ? SetThreadPriorityResult::SUCCESS
304 : SetThreadPriorityResult::FAILURE;
305#elif defined(__APPLE__)
316 const auto qosClass = [&]() {
318 case ThreadPriority::Background:
319 return QOS_CLASS_BACKGROUND;
320 case ThreadPriority::Low:
321 return QOS_CLASS_UTILITY;
322 case ThreadPriority::Default:
323 return QOS_CLASS_DEFAULT;
326 return !pthread_set_qos_class_self_np(qosClass, 0)
327 ? SetThreadPriorityResult::SUCCESS
328 : SetThreadPriorityResult::FAILURE;
330 return SetThreadPriorityResult::FAILURE;
335static int computeHostNumHardwareThreads() {
336#if defined(__FreeBSD__)
339 if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
sizeof(
mask),
341 return CPU_COUNT(&
mask);
342#elif (defined(__linux__) || defined(__CYGWIN__))
345 if (sched_getaffinity(0,
sizeof(Set), &Set) == 0)
346 return CPU_COUNT(&Set);
349 if (
unsigned Val = std::thread::hardware_concurrency())
355 unsigned ThreadPoolNum)
const {}
364#if (defined(__linux__) || defined(__CYGWIN__)) && \
365 (defined(__i386__) || defined(__x86_64__))
369static int computeHostNumPhysicalCores() {
373 if (sched_getaffinity(0,
sizeof(Affinity), &Affinity) != 0)
381 if (std::error_code EC =
Text.getError()) {
383 <<
"/proc/cpuinfo: " <<
EC.message() <<
"\n";
387 (*Text)->getBuffer().split(strs,
"\n", -1,
389 int CurProcessor = -1;
390 int CurPhysicalId = -1;
391 int CurSiblings = -1;
394 std::pair<llvm::StringRef, llvm::StringRef>
Data =
Line.split(
':');
396 auto Val =
Data.second.trim();
398 if (Name ==
"processor")
399 Val.getAsInteger(10, CurProcessor);
400 else if (Name ==
"physical id")
401 Val.getAsInteger(10, CurPhysicalId);
402 else if (Name ==
"siblings")
403 Val.getAsInteger(10, CurSiblings);
404 else if (Name ==
"core id") {
405 Val.getAsInteger(10, CurCoreId);
407 if (CPU_ISSET(CurProcessor, &Affinity))
408 CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &
Enabled);
413#elif (defined(__linux__) && defined(__s390x__)) || defined(_AIX)
414static int computeHostNumPhysicalCores() {
415 return sysconf(_SC_NPROCESSORS_ONLN);
417#elif defined(__linux__)
418static int computeHostNumPhysicalCores() {
420 if (sched_getaffinity(0,
sizeof(Affinity), &Affinity) == 0)
421 return CPU_COUNT(&Affinity);
427 cpu_set_t *DynAffinity;
428 DynAffinity = CPU_ALLOC(2048);
429 if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
430 int NumCPUs = CPU_COUNT(DynAffinity);
431 CPU_FREE(DynAffinity);
436#elif defined(__APPLE__)
438static int computeHostNumPhysicalCores() {
440 size_t len =
sizeof(
count);
441 sysctlbyname(
"hw.physicalcpu", &
count, &len, NULL, 0);
446 sysctl(nm, 2, &
count, &len, NULL, 0);
452#elif defined(__MVS__)
453static int computeHostNumPhysicalCores() {
465 CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
468 char *CVT =
reinterpret_cast<char *
>(
469 static_cast<uintptr_t
>(
reinterpret_cast<unsigned int &
>(PSA[FLCCVT])));
470 char *CSD =
reinterpret_cast<char *
>(
471 static_cast<uintptr_t
>(
reinterpret_cast<unsigned int &
>(CVT[CVTCSD])));
472 return reinterpret_cast<int &
>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
476static int computeHostNumPhysicalCores() {
return -1; }
480 static int NumCores = computeHostNumPhysicalCores();
static constexpr unsigned long long mask(BlockVerifier::State S)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallString class.
This file defines the SmallVector class.
static void ReportErrnumFatal(const char *Msg, int errnum)
Represents either an error or a value T.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
LLVM_ABI void apply_thread_strategy(unsigned ThreadPoolNum) const
Assign the current thread to an ideal hardware CPU or NUMA node.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI llvm::BitVector get_thread_affinity_mask()
Returns a mask that represents on which hardware thread, core, CPU, NUMA group, the calling thread ca...
LLVM_ABI uint32_t get_max_thread_name_length()
Get the maximum length of a thread name on this platform.
LLVM_ABI SetThreadPriorityResult set_thread_priority(ThreadPriority Priority)
LLVM_ABI unsigned get_cpus()
Returns how many physical CPUs or NUMA groups the system has.
LLVM_ABI void set_thread_name(const Twine &Name)
Set the name of the current thread.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void get_thread_name(SmallVectorImpl< char > &Name)
Get the name of the current thread.
LLVM_ABI int get_physical_cores()
Returns how many physical cores (as opposed to logical cores returned from thread::hardware_concurren...
LLVM_ABI uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.