xref: /llvm-project/llvm/lib/Support/Threading.cpp (revision 5577207d6d3e0642ea047a8dfbfcf3ad372a7f25)
1 //===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines helper functions for running LLVM in a multi-threaded
10 // environment.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/Threading.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Config/config.h"
19 #include "llvm/Config/llvm-config.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 #include <cassert>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 using namespace llvm;
29 
30 //===----------------------------------------------------------------------===//
31 //=== WARNING: Implementation here must contain only TRULY operating system
32 //===          independent code.
33 //===----------------------------------------------------------------------===//
34 
35 #if LLVM_ENABLE_THREADS == 0 ||                                                \
36     (!defined(_WIN32) && !defined(HAVE_PTHREAD_H))
37 uint64_t llvm::get_threadid() { return 0; }
38 
39 uint32_t llvm::get_max_thread_name_length() { return 0; }
40 
41 void llvm::set_thread_name(const Twine &Name) {}
42 
43 void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); }
44 
45 llvm::BitVector llvm::get_thread_affinity_mask() { return {}; }
46 
47 unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
48   // When threads are disabled, ensure clients will loop at least once.
49   return 1;
50 }
51 
52 #else
53 
54 static int computeHostNumHardwareThreads();
55 
56 unsigned llvm::ThreadPoolStrategy::compute_thread_count() const {
57   int MaxThreadCount =
58       UseHyperThreads ? computeHostNumHardwareThreads() : get_physical_cores();
59   if (MaxThreadCount <= 0)
60     MaxThreadCount = 1;
61   if (ThreadsRequested == 0)
62     return MaxThreadCount;
63   if (!Limit)
64     return ThreadsRequested;
65   return std::min((unsigned)MaxThreadCount, ThreadsRequested);
66 }
67 
68 // Include the platform-specific parts of this class.
69 #ifdef LLVM_ON_UNIX
70 #include "Unix/Threading.inc"
71 #endif
72 #ifdef _WIN32
73 #include "Windows/Threading.inc"
74 #endif
75 
76 // Must be included after Threading.inc to provide definition for llvm::thread
77 // because FreeBSD's condvar.h (included by user.h) misuses the "thread"
78 // keyword.
79 #include "llvm/Support/thread.h"
80 
81 #if defined(__APPLE__)
82   // Darwin's default stack size for threads except the main one is only 512KB,
83   // which is not enough for some/many normal LLVM compilations. This implements
84   // the same interface as std::thread but requests the same stack size as the
85   // main thread (8MB) before creation.
86 const llvm::Optional<unsigned> llvm::thread::DefaultStackSize = 8 * 1024 * 1024;
87 #else
88 const llvm::Optional<unsigned> llvm::thread::DefaultStackSize;
89 #endif
90 
91 
92 #endif
93 
94 Optional<ThreadPoolStrategy>
95 llvm::get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default) {
96   if (Num == "all")
97     return llvm::hardware_concurrency();
98   if (Num.empty())
99     return Default;
100   unsigned V;
101   if (Num.getAsInteger(10, V))
102     return None; // malformed 'Num' value
103   if (V == 0)
104     return Default;
105 
106   // Do not take the Default into account. This effectively disables
107   // heavyweight_hardware_concurrency() if the user asks for any number of
108   // threads on the cmd-line.
109   ThreadPoolStrategy S = llvm::hardware_concurrency();
110   S.ThreadsRequested = V;
111   return S;
112 }
113 
114 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
115 // On Linux, the number of physical cores can be computed from /proc/cpuinfo,
116 // using the number of unique physical/core id pairs. The following
117 // implementation reads the /proc/cpuinfo format on an x86_64 system.
118 static int computeHostNumPhysicalCores() {
119   // Enabled represents the number of physical id/core id pairs with at least
120   // one processor id enabled by the CPU affinity mask.
121   cpu_set_t Affinity, Enabled;
122   if (sched_getaffinity(0, sizeof(Affinity), &Affinity) != 0)
123     return -1;
124   CPU_ZERO(&Enabled);
125 
126   // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
127   // mmapped because it appears to have 0 size.
128   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
129       llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
130   if (std::error_code EC = Text.getError()) {
131     llvm::errs() << "Can't read "
132                  << "/proc/cpuinfo: " << EC.message() << "\n";
133     return -1;
134   }
135   SmallVector<StringRef, 8> strs;
136   (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
137                              /*KeepEmpty=*/false);
138   int CurProcessor = -1;
139   int CurPhysicalId = -1;
140   int CurSiblings = -1;
141   int CurCoreId = -1;
142   for (StringRef Line : strs) {
143     std::pair<StringRef, StringRef> Data = Line.split(':');
144     auto Name = Data.first.trim();
145     auto Val = Data.second.trim();
146     // These fields are available if the kernel is configured with CONFIG_SMP.
147     if (Name == "processor")
148       Val.getAsInteger(10, CurProcessor);
149     else if (Name == "physical id")
150       Val.getAsInteger(10, CurPhysicalId);
151     else if (Name == "siblings")
152       Val.getAsInteger(10, CurSiblings);
153     else if (Name == "core id") {
154       Val.getAsInteger(10, CurCoreId);
155       // The processor id corresponds to an index into cpu_set_t.
156       if (CPU_ISSET(CurProcessor, &Affinity))
157         CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &Enabled);
158     }
159   }
160   return CPU_COUNT(&Enabled);
161 }
162 #elif defined(__linux__) && defined(__s390x__)
163 static int computeHostNumPhysicalCores() {
164   return sysconf(_SC_NPROCESSORS_ONLN);
165 }
166 #elif defined(__linux__) && !defined(__ANDROID__)
167 static int computeHostNumPhysicalCores() {
168   cpu_set_t Affinity;
169   if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0)
170     return CPU_COUNT(&Affinity);
171 
172   // The call to sched_getaffinity() may have failed because the Affinity
173   // mask is too small for the number of CPU's on the system (i.e. the
174   // system has more than 1024 CPUs). Allocate a mask large enough for
175   // twice as many CPUs.
176   cpu_set_t *DynAffinity;
177   DynAffinity = CPU_ALLOC(2048);
178   if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
179     int NumCPUs = CPU_COUNT(DynAffinity);
180     CPU_FREE(DynAffinity);
181     return NumCPUs;
182   }
183   return -1;
184 }
185 #elif defined(__APPLE__)
186 // Gets the number of *physical cores* on the machine.
187 static int computeHostNumPhysicalCores() {
188   uint32_t count;
189   size_t len = sizeof(count);
190   sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
191   if (count < 1) {
192     int nm[2];
193     nm[0] = CTL_HW;
194     nm[1] = HW_AVAILCPU;
195     sysctl(nm, 2, &count, &len, NULL, 0);
196     if (count < 1)
197       return -1;
198   }
199   return count;
200 }
201 #elif defined(__MVS__)
202 static int computeHostNumPhysicalCores() {
203   enum {
204     // Byte offset of the pointer to the Communications Vector Table (CVT) in
205     // the Prefixed Save Area (PSA). The table entry is a 31-bit pointer and
206     // will be zero-extended to uintptr_t.
207     FLCCVT = 16,
208     // Byte offset of the pointer to the Common System Data Area (CSD) in the
209     // CVT. The table entry is a 31-bit pointer and will be zero-extended to
210     // uintptr_t.
211     CVTCSD = 660,
212     // Byte offset to the number of live CPs in the LPAR, stored as a signed
213     // 32-bit value in the table.
214     CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
215   };
216   char *PSA = 0;
217   char *CVT = reinterpret_cast<char *>(
218       static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(PSA[FLCCVT])));
219   char *CSD = reinterpret_cast<char *>(
220       static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(CVT[CVTCSD])));
221   return reinterpret_cast<int &>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
222 }
223 #elif defined(_WIN32) && LLVM_ENABLE_THREADS != 0
224 // Defined in llvm/lib/Support/Windows/Threading.inc
225 int computeHostNumPhysicalCores();
226 #else
227 // On other systems, return -1 to indicate unknown.
228 static int computeHostNumPhysicalCores() { return -1; }
229 #endif
230 
231 int llvm::get_physical_cores() {
232   static int NumCores = computeHostNumPhysicalCores();
233   return NumCores;
234 }
235