From cf21fddda97b2bd137154213e1b49e02d9576788 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Mon, 18 Jul 2016 16:33:31 -0700 Subject: [PATCH] folly: improve setThreadName for macOS Summary: Since OS X 10.6 it is possible to set the name of the current thread. This diff adjusts our setThreadName routine to do this, partially fixing the associated test case. Even though this doesn't completely cover all cases it is still a valid improvement: most callers are threads setting their own name. I've amended the tests so that they can accomodate systems that cannot set the names of other threads. Reviewed By: yfeldblum Differential Revision: D3576281 fbshipit-source-id: 13caf0dca6496aa2da897631e8d7327a6ee452bb --- folly/ThreadName.h | 23 +++++++++++++++++++++-- folly/test/ThreadNameTest.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/folly/ThreadName.h b/folly/ThreadName.h index 1f745e77..333a329d 100644 --- a/folly/ThreadName.h +++ b/folly/ThreadName.h @@ -26,7 +26,14 @@ namespace folly { // having an undefined compiler function called. #if defined(__GLIBC__) && !defined(__APPLE__) && !defined(__ANDROID__) #if __GLIBC_PREREQ(2, 12) -# define FOLLY_HAS_PTHREAD_SETNAME_NP +// has pthread_setname_np(pthread_t, const char*) (2 params) +#define FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME 1 +#endif +#endif +#if defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +// has pthread_setname_np(const char*) (1 param) +#define FOLLY_HAS_PTHREAD_SETNAME_NP_NAME 1 #endif #endif @@ -39,13 +46,25 @@ inline bool setThreadName(T /* id */, StringPiece /* name */) { return false; } -#ifdef FOLLY_HAS_PTHREAD_SETNAME_NP +#ifdef FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME template <> inline bool setThreadName(pthread_t id, StringPiece name) { return 0 == pthread_setname_np(id, name.fbstr().substr(0, 15).c_str()); } #endif +#ifdef FOLLY_HAS_PTHREAD_SETNAME_NP_NAME +template <> +inline bool setThreadName(pthread_t id, StringPiece name) { + // Since OS X 10.6 it is possible for a thread to set its own name, + // but not that of some other thread. + if (pthread_equal(pthread_self(), id)) { + return 0 == pthread_setname_np(name.fbstr().c_str()); + } + return false; +} +#endif + inline bool setThreadName(StringPiece name) { return setThreadName(pthread_self(), name); } diff --git a/folly/test/ThreadNameTest.cpp b/folly/test/ThreadNameTest.cpp index d85ef2c4..ec59687a 100644 --- a/folly/test/ThreadNameTest.cpp +++ b/folly/test/ThreadNameTest.cpp @@ -22,9 +22,26 @@ using namespace std; using namespace folly; +constexpr bool expectedSetOtherThreadNameResult = +#ifdef FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME + true +#else + false // This system has no known way to set the name of another thread +#endif + ; + +constexpr bool expectedSetSelfThreadNameResult = +#if defined(FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME) || \ + defined(FOLLY_HAS_PTHREAD_SETNAME_NP_NAME) + true +#else + false // This system has no known way to set its own thread name +#endif + ; + TEST(ThreadName, setThreadName_self) { thread th([] { - EXPECT_TRUE(setThreadName("rockin-thread")); + EXPECT_EQ(expectedSetSelfThreadNameResult, setThreadName("rockin-thread")); }); SCOPE_EXIT { th.join(); }; } @@ -41,7 +58,8 @@ TEST(ThreadName, setThreadName_other_pthread) { SCOPE_EXIT { th.join(); }; handle_set.wait(); SCOPE_EXIT { let_thread_end.post(); }; - EXPECT_TRUE(setThreadName(handle, "rockin-thread")); + EXPECT_EQ( + expectedSetOtherThreadNameResult, setThreadName(handle, "rockin-thread")); } TEST(ThreadName, setThreadName_other_native) { @@ -51,5 +69,7 @@ TEST(ThreadName, setThreadName_other_native) { }); SCOPE_EXIT { th.join(); }; SCOPE_EXIT { let_thread_end.post(); }; - EXPECT_TRUE(setThreadName(th.native_handle(), "rockin-thread")); + EXPECT_EQ( + expectedSetOtherThreadNameResult, + setThreadName(th.native_handle(), "rockin-thread")); } -- 2.34.1