blob: 48750cef5ec22e4aff34be4b21a54aeb1101a4f3 [file] [log] [blame]
Charles Davis54c9eb62010-11-29 19:44:50 +00001//===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
Owen Anderson4cb4b612009-06-16 17:33:51 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Owen Anderson4cb4b612009-06-16 17:33:51 +00006//
7//===----------------------------------------------------------------------===//
8//
Chandler Carruth39cd2162014-06-27 15:13:01 +00009// This file defines helper functions for running LLVM in a multi-threaded
10// environment.
Owen Anderson4cb4b612009-06-16 17:33:51 +000011//
12//===----------------------------------------------------------------------===//
13
Michael J. Spencer447762d2010-11-29 18:16:10 +000014#include "llvm/Support/Threading.h"
Sam McCalla9c3c172019-10-23 15:34:48 +020015#include "llvm/ADT/Optional.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "llvm/Config/config.h"
Teresa Johnson2bd812c2016-10-14 00:13:59 +000017#include "llvm/Support/Host.h"
Zachary Turner757dbc92017-03-03 17:15:17 +000018
Owen Anderson4cb4b612009-06-16 17:33:51 +000019#include <cassert>
Zachary Turner757dbc92017-03-03 17:15:17 +000020#include <errno.h>
21#include <stdlib.h>
22#include <string.h>
Owen Anderson2370b4d2009-07-06 21:24:37 +000023
Owen Anderson4cb4b612009-06-16 17:33:51 +000024using namespace llvm;
25
Zachary Turner757dbc92017-03-03 17:15:17 +000026//===----------------------------------------------------------------------===//
27//=== WARNING: Implementation here must contain only TRULY operating system
28//=== independent code.
29//===----------------------------------------------------------------------===//
30
Chandler Carruth39cd2162014-06-27 15:13:01 +000031bool llvm::llvm_is_multithreaded() {
Dylan Noblesmithefddf202011-11-28 00:48:58 +000032#if LLVM_ENABLE_THREADS != 0
Owen Anderson4cb4b612009-06-16 17:33:51 +000033 return true;
34#else
35 return false;
36#endif
37}
38
Zachary Turner757dbc92017-03-03 17:15:17 +000039#if LLVM_ENABLE_THREADS == 0 || \
Nico Weber712e8d22018-04-29 00:45:03 +000040 (!defined(_WIN32) && !defined(HAVE_PTHREAD_H))
NAKAMURA Takumidbd883b2011-09-19 07:41:43 +000041// Support for non-Win32, non-pthread implementation.
Zachary Turner757dbc92017-03-03 17:15:17 +000042void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData,
Sam McCalla9c3c172019-10-23 15:34:48 +020043 llvm::Optional<unsigned> StackSizeInBytes) {
44 (void)StackSizeInBytes;
Daniel Dunbarcdd4c542010-11-04 01:26:25 +000045 Fn(UserData);
46}
47
Zachary Turner757dbc92017-03-03 17:15:17 +000048unsigned llvm::heavyweight_hardware_concurrency() { return 1; }
49
Rafael Espindola8c0ff952017-10-04 20:27:01 +000050unsigned llvm::hardware_concurrency() { return 1; }
51
Zachary Turner640cee02017-03-03 21:49:38 +000052uint64_t llvm::get_threadid() { return 0; }
Zachary Turner757dbc92017-03-03 17:15:17 +000053
Zachary Turner1f004c42017-03-04 18:53:09 +000054uint32_t llvm::get_max_thread_name_length() { return 0; }
55
Zachary Turner757dbc92017-03-03 17:15:17 +000056void llvm::set_thread_name(const Twine &Name) {}
57
58void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); }
59
Sam McCalla9c3c172019-10-23 15:34:48 +020060#if LLVM_ENABLE_THREADS == 0
61void llvm::llvm_execute_on_thread_async(
62 llvm::unique_function<void()> Func,
63 llvm::Optional<unsigned> StackSizeInBytes) {
64 (void)Func;
65 (void)StackSizeInBytes;
66 report_fatal_error("Spawning a detached thread doesn't make sense with no "
67 "threading support");
68}
69#else
70// Support for non-Win32, non-pthread implementation.
71void llvm::llvm_execute_on_thread_async(
72 llvm::unique_function<void()> Func,
73 llvm::Optional<unsigned> StackSizeInBytes) {
74 (void)StackSizeInBytes;
75 std::thread(std::move(Func)).detach();
76}
77#endif
78
Zachary Turner757dbc92017-03-03 17:15:17 +000079#else
Teresa Johnson2bd812c2016-10-14 00:13:59 +000080
Zachary Turner91db01f2017-03-03 17:39:24 +000081#include <thread>
Teresa Johnsonc0ef9e42016-10-17 14:56:53 +000082unsigned llvm::heavyweight_hardware_concurrency() {
Zachary Turner91db01f2017-03-03 17:39:24 +000083 // Since we can't get here unless LLVM_ENABLE_THREADS == 1, it is safe to use
84 // `std::thread` directly instead of `llvm::thread` (and indeed, doing so
85 // allows us to not define `thread` in the llvm namespace, which conflicts
86 // with some platforms such as FreeBSD whose headers also define a struct
87 // called `thread` in the global namespace which can cause ambiguity due to
88 // ADL.
Teresa Johnson2bd812c2016-10-14 00:13:59 +000089 int NumPhysical = sys::getHostNumPhysicalCores();
90 if (NumPhysical == -1)
Zachary Turner91db01f2017-03-03 17:39:24 +000091 return std::thread::hardware_concurrency();
Teresa Johnson2bd812c2016-10-14 00:13:59 +000092 return NumPhysical;
93}
Zachary Turner757dbc92017-03-03 17:15:17 +000094
Rafael Espindola8c0ff952017-10-04 20:27:01 +000095unsigned llvm::hardware_concurrency() {
96#if defined(HAVE_SCHED_GETAFFINITY) && defined(HAVE_CPU_COUNT)
97 cpu_set_t Set;
98 if (sched_getaffinity(0, sizeof(Set), &Set))
99 return CPU_COUNT(&Set);
100#endif
101 // Guard against std::thread::hardware_concurrency() returning 0.
102 if (unsigned Val = std::thread::hardware_concurrency())
103 return Val;
104 return 1;
105}
106
Sam McCalla9c3c172019-10-23 15:34:48 +0200107namespace {
108struct SyncThreadInfo {
109 void (*UserFn)(void *);
110 void *UserData;
111};
112
113using AsyncThreadInfo = llvm::unique_function<void()>;
114
115enum class JoiningPolicy { Join, Detach };
116} // namespace
117
Zachary Turner757dbc92017-03-03 17:15:17 +0000118// Include the platform-specific parts of this class.
119#ifdef LLVM_ON_UNIX
120#include "Unix/Threading.inc"
121#endif
Nico Weber712e8d22018-04-29 00:45:03 +0000122#ifdef _WIN32
Zachary Turner757dbc92017-03-03 17:15:17 +0000123#include "Windows/Threading.inc"
124#endif
125
Sam McCalla9c3c172019-10-23 15:34:48 +0200126void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData,
127 llvm::Optional<unsigned> StackSizeInBytes) {
128
129 SyncThreadInfo Info = {Fn, UserData};
130 llvm_execute_on_thread_impl(threadFuncSync, &Info, StackSizeInBytes,
131 JoiningPolicy::Join);
132}
133
134void llvm::llvm_execute_on_thread_async(
135 llvm::unique_function<void()> Func,
136 llvm::Optional<unsigned> StackSizeInBytes) {
137 llvm_execute_on_thread_impl(&threadFuncAsync,
138 new AsyncThreadInfo(std::move(Func)),
139 StackSizeInBytes, JoiningPolicy::Detach);
140}
141
Zachary Turner757dbc92017-03-03 17:15:17 +0000142#endif