19 #include <type_traits> 30 #if defined(__GLIBC__) && !defined(__APPLE__) && !defined(__ANDROID__) 31 #if __GLIBC_PREREQ(2, 12) 33 #define FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME 1 37 #if defined(__APPLE__) 38 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ 39 __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 41 #define FOLLY_HAS_PTHREAD_SETNAME_NP_NAME 1 42 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ 43 __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200 45 #define FOLLY_HAS_PTHREAD_SETNAME_NP_NAME 1 47 #endif // defined(__APPLE__) 51 #if FOLLY_HAVE_PTHREAD && !_WIN32 52 pthread_t stdTidToPthreadId(std::thread::id tid) {
55 "This assumes that the native handle type is pthread_t");
57 sizeof(std::thread::native_handle_type) ==
sizeof(std::thread::id),
58 "This assumes std::thread::id is a thin wrapper around " 59 "std::thread::native_handle_type, but that doesn't appear to be true.");
64 std::memcpy(&
id, &tid,
sizeof(
id));
72 #if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME || \ 73 FOLLY_HAS_PTHREAD_SETNAME_NP_NAME || _WIN32 81 #if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME || _WIN32 91 #if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME || \ 92 FOLLY_HAS_PTHREAD_SETNAME_NP_NAME 93 std::array<char, kMaxThreadNameLength> buf;
94 if (pthread_getname_np(stdTidToPthreadId(
id), buf.data(), buf.size()) != 0) {
110 auto trimmedName = name.
subpiece(0, kMaxThreadNameLength - 1).
str();
113 sizeof(
unsigned int) ==
sizeof(std::thread::id),
114 "This assumes std::thread::id is a thin wrapper around " 115 "the thread id as an unsigned int, but that doesn't appear to be true.");
118 #pragma pack(push, 8) 119 struct THREADNAME_INFO {
127 ULONG_PTR upArray[4];
131 static constexpr DWORD kMSVCException = 0x406D1388;
136 std::memcpy(&
id, &tid,
sizeof(
id));
138 TNIUnion tniUnion = {0x1000, trimmedName.data(), id, 0};
143 RaiseException(kMSVCException, 0, 4, tniUnion.upArray);
145 GetExceptionCode() == kMSVCException ? EXCEPTION_CONTINUE_EXECUTION
146 : EXCEPTION_EXECUTE_HANDLER) {
152 name = name.
subpiece(0, kMaxThreadNameLength - 1);
154 std::memcpy(buf, name.
data(), name.
size());
155 auto id = stdTidToPthreadId(tid);
156 #if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME 157 return 0 == pthread_setname_np(
id, buf);
158 #elif FOLLY_HAS_PTHREAD_SETNAME_NP_NAME 161 if (pthread_equal(pthread_self(),
id)) {
162 return 0 == pthread_setname_np(buf);
175 sizeof(
unsigned int) ==
sizeof(std::thread::id),
176 "This assumes std::thread::id is a thin wrapper around " 177 "the thread id as an unsigned int, but that doesn't appear to be true.");
181 unsigned int tid = pthread_getw32threadid_np(pid);
183 std::memcpy(&
id, &tid,
sizeof(
id));
188 "This assumes that the native handle type is pthread_t");
190 sizeof(std::thread::native_handle_type) ==
sizeof(std::thread::id),
191 "This assumes std::thread::id is a thin wrapper around " 192 "std::thread::native_handle_type, but that doesn't appear to be true.");
197 std::memcpy(static_cast<void*>(&
id), &pid,
sizeof(
id));
Optional< std::string > getThreadName(std::thread::id id)
bool canSetOtherThreadName()
constexpr size_type size() const
—— Concurrent Priority Queue Implementation ——
constexpr Optional< _t< std::decay< T > > > make_optional(T &&v)
constexpr Iter data() const
Range subpiece(size_type first, size_type length=npos) const
bool canSetCurrentThreadName()
static const char *const value
bool setThreadName(std::thread::id tid, StringPiece name)
static constexpr size_t kMaxThreadNameLength
Optional< std::string > getCurrentThreadName()