1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00
llvm-mirror/lib/Support/Unix/Threading.inc
Chandler Carruth eb66b33867 Sort the remaining #include lines in include/... and lib/....
I did this a long time ago with a janky python script, but now
clang-format has built-in support for this. I fed clang-format every
line with a #include and let it re-sort things according to the precise
LLVM rules for include ordering baked into clang-format these days.

I've reverted a number of files where the results of sorting includes
isn't healthy. Either places where we have legacy code relying on
particular include ordering (where possible, I'll fix these separately)
or where we have particular formatting around #include lines that
I didn't want to disturb in this patch.

This patch is *entirely* mechanical. If you get merge conflicts or
anything, just ignore the changes in this patch and run clang-format
over your #include lines in the files.

Sorry for any noise here, but it is important to keep these things
stable. I was seeing an increasing number of patches with irrelevant
re-ordering of #include lines because clang-format was used. This patch
at least isolates that churn, makes it easy to skip when resolving
conflicts, and gets us to a clean baseline (again).

llvm-svn: 304787
2017-06-06 11:49:48 +00:00

216 lines
5.7 KiB
C++

//===- Unix/Threading.inc - Unix Threading Implementation ----- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides the Unix specific implementation of Threading functions.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#if defined(__APPLE__)
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#endif
#include <pthread.h>
#if defined(__FreeBSD__)
#include <pthread_np.h> // For pthread_getthreadid_np()
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <errno.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <unistd.h>
#endif
#if defined(__NetBSD__)
#include <lwp.h> // For _lwp_self()
#endif
#if defined(__linux__)
#include <sys/syscall.h> // For syscall codes
#include <unistd.h> // For syscall()
#endif
namespace {
struct ThreadInfo {
void(*UserFn)(void *);
void *UserData;
};
}
static void *ExecuteOnThread_Dispatch(void *Arg) {
ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
TI->UserFn(TI->UserData);
return nullptr;
}
void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData,
unsigned RequestedStackSize) {
ThreadInfo Info = { Fn, UserData };
pthread_attr_t Attr;
pthread_t Thread;
// Construct the attributes object.
if (::pthread_attr_init(&Attr) != 0)
return;
// Set the requested stack size, if given.
if (RequestedStackSize != 0) {
if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0)
goto error;
}
// Construct and execute the thread.
if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0)
goto error;
// Wait for the thread and clean up.
::pthread_join(Thread, nullptr);
error:
::pthread_attr_destroy(&Attr);
}
uint64_t llvm::get_threadid() {
#if defined(__APPLE__)
// Calling "mach_thread_self()" bumps the reference count on the thread
// port, so we need to deallocate it. mach_task_self() doesn't bump the ref
// count.
thread_port_t Self = mach_thread_self();
mach_port_deallocate(mach_task_self(), Self);
return Self;
#elif defined(__FreeBSD__)
return uint64_t(pthread_getthreadid_np());
#elif defined(__NetBSD__)
return uint64_t(_lwp_self());
#elif defined(__ANDROID__)
return uint64_t(gettid());
#elif defined(__linux__)
return uint64_t(syscall(SYS_gettid));
#elif defined(LLVM_ON_WIN32)
return uint64_t(::GetCurrentThreadId());
#else
return uint64_t(pthread_self());
#endif
}
static constexpr uint32_t get_max_thread_name_length_impl() {
#if defined(__NetBSD__)
return PTHREAD_MAX_NAMELEN_NP;
#elif defined(__APPLE__)
return 64;
#elif defined(__linux__)
#if HAVE_PTHREAD_SETNAME_NP
return 16;
#else
return 0;
#endif
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
return 16;
#else
return 0;
#endif
}
uint32_t llvm::get_max_thread_name_length() {
return get_max_thread_name_length_impl();
}
void llvm::set_thread_name(const Twine &Name) {
// Make sure the input is null terminated.
SmallString<64> Storage;
StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
// Truncate from the beginning, not the end, if the specified name is too
// long. For one, this ensures that the resulting string is still null
// terminated, but additionally the end of a long thread name will usually
// be more unique than the beginning, since a common pattern is for similar
// threads to share a common prefix.
if (get_max_thread_name_length() > 0)
NameStr = NameStr.take_back(get_max_thread_name_length());
(void)NameStr;
#if defined(__linux__)
#if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || defined(__ANDROID__)
#if HAVE_PTHREAD_SETNAME_NP
::pthread_setname_np(::pthread_self(), NameStr.data());
#endif
#endif
#elif defined(__FreeBSD__)
::pthread_set_name_np(::pthread_self(), NameStr.data());
#elif defined(__NetBSD__)
::pthread_setname_np(::pthread_self(), "%s",
const_cast<char *>(NameStr.data()));
#elif defined(__APPLE__)
::pthread_setname_np(NameStr.data());
#endif
}
void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
Name.clear();
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
int pid = ::getpid();
uint64_t tid = get_threadid();
struct kinfo_proc *kp = nullptr, *nkp;
size_t len = 0;
int error;
int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
(int)pid };
while (1) {
error = sysctl(ctl, 4, kp, &len, nullptr, 0);
if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
// Add extra space in case threads are added before next call.
len += sizeof(*kp) + len / 10;
nkp = (struct kinfo_proc *)realloc(kp, len);
if (nkp == nullptr) {
free(kp);
return;
}
kp = nkp;
continue;
}
if (error != 0)
len = 0;
break;
}
for (size_t i = 0; i < len / sizeof(*kp); i++) {
if (kp[i].ki_tid == (lwpid_t)tid) {
Name.append(kp[i].ki_tdname, kp[i].ki_tdname + strlen(kp[i].ki_tdname));
break;
}
}
free(kp);
return;
#elif defined(__NetBSD__)
constexpr uint32_t len = get_max_thread_name_length_impl();
char buf[len];
::pthread_getname_np(::pthread_self(), buf, len);
Name.append(buf, buf + strlen(buf));
#elif defined(__linux__)
#if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || defined(__ANDROID__)
#if HAVE_PTHREAD_GETNAME_NP
constexpr uint32_t len = get_max_thread_name_length_impl();
char Buffer[len];
if (0 == ::pthread_getname_np(::pthread_self(), Buffer, len))
Name.append(Buffer, Buffer + strlen(Buffer));
#endif
#endif
#endif
}