18 #if defined(__APPLE__)
19 #include <mach/mach_init.h>
20 #include <mach/mach_port.h>
21 #include <pthread/qos.h>
26 #if defined(__FreeBSD__) || defined(__OpenBSD__)
27 #include <pthread_np.h>
30 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
32 #include <sys/cpuset.h>
33 #include <sys/sysctl.h>
38 #if defined(__NetBSD__)
42 #if defined(__OpenBSD__)
46 #if defined(__linux__)
48 #include <sys/syscall.h>
60 if ((errnum = ::pthread_attr_init(&Attr)) != 0) {
65 if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) {
71 if (StackSizeInBytes) {
72 if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) {
79 if ((errnum = ::pthread_create(&
Thread, &Attr, ThreadFunc,
Arg)) != 0)
88 if ((errnum = ::pthread_detach(
Thread)) != 0) {
96 if ((errnum = ::pthread_join(
Thread,
nullptr)) != 0) {
106 return ::pthread_self();
112 #if defined(__APPLE__)
116 thread_port_t Self = mach_thread_self();
117 mach_port_deallocate(mach_task_self(), Self);
119 #elif defined(__FreeBSD__)
120 return uint64_t(pthread_getthreadid_np());
121 #elif defined(__NetBSD__)
123 #elif defined(__OpenBSD__)
125 #elif defined(__ANDROID__)
127 #elif defined(__linux__)
128 return uint64_t(syscall(SYS_gettid));
135 static constexpr
uint32_t get_max_thread_name_length_impl() {
136 #if defined(__NetBSD__)
137 return PTHREAD_MAX_NAMELEN_NP;
138 #elif defined(__APPLE__)
140 #elif defined(__linux__)
141 #if HAVE_PTHREAD_SETNAME_NP
146 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
148 #elif defined(__OpenBSD__)
156 return get_max_thread_name_length_impl();
161 SmallString<64> Storage;
162 StringRef NameStr =
Name.toNullTerminatedStringRef(Storage);
173 #if defined(__linux__)
174 #if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || defined(__ANDROID__)
175 #if HAVE_PTHREAD_SETNAME_NP
176 ::pthread_setname_np(::pthread_self(), NameStr.data());
179 #elif defined(__FreeBSD__) || defined(__OpenBSD__)
180 ::pthread_set_name_np(::pthread_self(), NameStr.data());
181 #elif defined(__NetBSD__)
182 ::pthread_setname_np(::pthread_self(),
"%s",
183 const_cast<char *
>(NameStr.data()));
184 #elif defined(__APPLE__)
185 ::pthread_setname_np(NameStr.data());
192 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
193 int pid = ::getpid();
196 struct kinfo_proc *kp =
nullptr, *nkp;
199 int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
203 error = sysctl(ctl, 4, kp, &len,
nullptr, 0);
204 if (kp ==
nullptr || (
error != 0 && errno == ENOMEM)) {
206 len +=
sizeof(*kp) + len / 10;
207 nkp = (
struct kinfo_proc *)::realloc(kp, len);
208 if (nkp ==
nullptr) {
220 for (
size_t i = 0;
i < len /
sizeof(*kp);
i++) {
221 if (kp[
i].ki_tid == (lwpid_t)tid) {
222 Name.append(kp[
i].ki_tdname, kp[
i].ki_tdname + strlen(kp[
i].ki_tdname));
228 #elif defined(__NetBSD__)
229 constexpr
uint32_t len = get_max_thread_name_length_impl();
231 ::pthread_getname_np(::pthread_self(), buf, len);
233 Name.append(buf, buf + strlen(buf));
234 #elif defined(__OpenBSD__)
235 constexpr
uint32_t len = get_max_thread_name_length_impl();
237 ::pthread_get_name_np(::pthread_self(), buf, len);
239 Name.append(buf, buf + strlen(buf));
240 #elif defined(__linux__)
241 #if HAVE_PTHREAD_GETNAME_NP
242 constexpr
uint32_t len = get_max_thread_name_length_impl();
243 char Buffer[len] = {
'\0'};
244 if (0 == ::pthread_getname_np(::pthread_self(), Buffer, len))
245 Name.append(Buffer, Buffer + strlen(Buffer));
251 #if defined(__linux__) && defined(SCHED_IDLE)
255 sched_param priority;
257 priority.sched_priority = 0;
260 return !pthread_setschedparam(
265 ? SetThreadPriorityResult::SUCCESS
266 : SetThreadPriorityResult::FAILURE;
267 #elif defined(__APPLE__)
277 const auto qosClass = [&](){
279 case ThreadPriority::Background:
return QOS_CLASS_BACKGROUND;
280 case ThreadPriority::Low:
return QOS_CLASS_UTILITY;
284 return !pthread_set_qos_class_self_np(qosClass, 0)
285 ? SetThreadPriorityResult::SUCCESS
286 : SetThreadPriorityResult::FAILURE;
288 return SetThreadPriorityResult::FAILURE;
294 #if defined(__FreeBSD__)
297 if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
sizeof(mask),
299 return CPU_COUNT(&mask);
300 #elif defined(__linux__)
302 if (sched_getaffinity(0,
sizeof(Set), &Set) == 0)
303 return CPU_COUNT(&Set);
312 unsigned ThreadPoolNum)
const {}