1 //===- Unix/Threading.inc - Unix Threading Implementation ----- -*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides the Unix specific implementation of Threading functions.
11 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/ScopeExit.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/Twine.h"
18 #if defined(__APPLE__)
19 #include <mach/mach_init.h>
20 #include <mach/mach_port.h>
25 #if defined(__FreeBSD__) || defined(__OpenBSD__)
26 #include <pthread_np.h> // For pthread_getthreadid_np() / pthread_set_name_np()
29 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
31 #include <sys/sysctl.h>
36 #if defined(__NetBSD__)
37 #include <lwp.h> // For _lwp_self()
40 #if defined(__linux__)
41 #include <sys/syscall.h> // For syscall codes
42 #include <unistd.h> // For syscall()
45 static void *threadFuncSync(void *Arg) {
46 SyncThreadInfo *TI = static_cast<SyncThreadInfo *>(Arg);
47 TI->UserFn(TI->UserData);
51 static void *threadFuncAsync(void *Arg) {
52 std::unique_ptr<AsyncThreadInfo> Info(static_cast<AsyncThreadInfo *>(Arg));
58 llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg,
59 llvm::Optional<unsigned> StackSizeInBytes,
63 // Construct the attributes object.
65 if ((errnum = ::pthread_attr_init(&Attr)) != 0) {
66 ReportErrnumFatal("pthread_attr_init failed", errnum);
69 auto AttrGuard = llvm::make_scope_exit([&] {
70 if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) {
71 ReportErrnumFatal("pthread_attr_destroy failed", errnum);
75 // Set the requested stack size, if given.
76 if (StackSizeInBytes) {
77 if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) {
78 ReportErrnumFatal("pthread_attr_setstacksize failed", errnum);
82 // Construct and execute the thread.
84 if ((errnum = ::pthread_create(&Thread, &Attr, ThreadFunc, Arg)) != 0)
85 ReportErrnumFatal("pthread_create failed", errnum);
87 if (JP == JoiningPolicy::Join) {
88 // Wait for the thread
89 if ((errnum = ::pthread_join(Thread, nullptr)) != 0) {
90 ReportErrnumFatal("pthread_join failed", errnum);
95 uint64_t llvm::get_threadid() {
96 #if defined(__APPLE__)
97 // Calling "mach_thread_self()" bumps the reference count on the thread
98 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
100 thread_port_t Self = mach_thread_self();
101 mach_port_deallocate(mach_task_self(), Self);
103 #elif defined(__FreeBSD__)
104 return uint64_t(pthread_getthreadid_np());
105 #elif defined(__NetBSD__)
106 return uint64_t(_lwp_self());
107 #elif defined(__ANDROID__)
108 return uint64_t(gettid());
109 #elif defined(__linux__)
110 return uint64_t(syscall(SYS_gettid));
112 return uint64_t(pthread_self());
117 static constexpr uint32_t get_max_thread_name_length_impl() {
118 #if defined(__NetBSD__)
119 return PTHREAD_MAX_NAMELEN_NP;
120 #elif defined(__APPLE__)
122 #elif defined(__linux__)
123 #if HAVE_PTHREAD_SETNAME_NP
128 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
130 #elif defined(__OpenBSD__)
137 uint32_t llvm::get_max_thread_name_length() {
138 return get_max_thread_name_length_impl();
141 void llvm::set_thread_name(const Twine &Name) {
142 // Make sure the input is null terminated.
143 SmallString<64> Storage;
144 StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
146 // Truncate from the beginning, not the end, if the specified name is too
147 // long. For one, this ensures that the resulting string is still null
148 // terminated, but additionally the end of a long thread name will usually
149 // be more unique than the beginning, since a common pattern is for similar
150 // threads to share a common prefix.
151 // Note that the name length includes the null terminator.
152 if (get_max_thread_name_length() > 0)
153 NameStr = NameStr.take_back(get_max_thread_name_length() - 1);
155 #if defined(__linux__)
156 #if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || defined(__ANDROID__)
157 #if HAVE_PTHREAD_SETNAME_NP
158 ::pthread_setname_np(::pthread_self(), NameStr.data());
161 #elif defined(__FreeBSD__) || defined(__OpenBSD__)
162 ::pthread_set_name_np(::pthread_self(), NameStr.data());
163 #elif defined(__NetBSD__)
164 ::pthread_setname_np(::pthread_self(), "%s",
165 const_cast<char *>(NameStr.data()));
166 #elif defined(__APPLE__)
167 ::pthread_setname_np(NameStr.data());
171 void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
174 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
175 int pid = ::getpid();
176 uint64_t tid = get_threadid();
178 struct kinfo_proc *kp = nullptr, *nkp;
181 int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
185 error = sysctl(ctl, 4, kp, &len, nullptr, 0);
186 if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
187 // Add extra space in case threads are added before next call.
188 len += sizeof(*kp) + len / 10;
189 nkp = (struct kinfo_proc *)::realloc(kp, len);
190 if (nkp == nullptr) {
202 for (size_t i = 0; i < len / sizeof(*kp); i++) {
203 if (kp[i].ki_tid == (lwpid_t)tid) {
204 Name.append(kp[i].ki_tdname, kp[i].ki_tdname + strlen(kp[i].ki_tdname));
210 #elif defined(__NetBSD__)
211 constexpr uint32_t len = get_max_thread_name_length_impl();
213 ::pthread_getname_np(::pthread_self(), buf, len);
215 Name.append(buf, buf + strlen(buf));
216 #elif defined(__OpenBSD__)
217 constexpr uint32_t len = get_max_thread_name_length_impl();
219 ::pthread_get_name_np(::pthread_self(), buf, len);
221 Name.append(buf, buf + strlen(buf));
222 #elif defined(__linux__)
223 #if HAVE_PTHREAD_GETNAME_NP
224 constexpr uint32_t len = get_max_thread_name_length_impl();
225 char Buffer[len] = {'\0'}; // FIXME: working around MSan false positive.
226 if (0 == ::pthread_getname_np(::pthread_self(), Buffer, len))
227 Name.append(Buffer, Buffer + strlen(Buffer));
232 SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
233 #if defined(__linux__) && defined(SCHED_IDLE)
234 // Some *really* old glibcs are missing SCHED_IDLE.
235 // http://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html
236 // http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
237 sched_param priority;
238 // For each of the above policies, param->sched_priority must be 0.
239 priority.sched_priority = 0;
240 // SCHED_IDLE for running very low priority background jobs.
241 // SCHED_OTHER the standard round-robin time-sharing policy;
242 return !pthread_setschedparam(
244 Priority == ThreadPriority::Background ? SCHED_IDLE : SCHED_OTHER,
246 ? SetThreadPriorityResult::SUCCESS
247 : SetThreadPriorityResult::FAILURE;
248 #elif defined(__APPLE__)
249 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpriority.2.html
250 // When setting a thread into background state the scheduling priority is set
251 // to lowest value, disk and network IO are throttled. Network IO will be
252 // throttled for any sockets the thread opens after going into background
253 // state. Any previously opened sockets are not affected.
255 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/getiopolicy_np.3.html
256 // I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O
257 // request occurs within a small time window (usually a fraction of a second)
258 // of another NORMAL I/O request, the thread that issues the THROTTLE I/O is
259 // forced to sleep for a certain interval. This slows down the thread that
260 // issues the THROTTLE I/O so that NORMAL I/Os can utilize most of the disk
262 return !setpriority(PRIO_DARWIN_THREAD, 0,
263 Priority == ThreadPriority::Background ? PRIO_DARWIN_BG
265 ? SetThreadPriorityResult::SUCCESS
266 : SetThreadPriorityResult::FAILURE;
268 return SetThreadPriorityResult::FAILURE;