folly: improve setThreadName for macOS
authorWez Furlong <wez@fb.com>
Mon, 18 Jul 2016 23:33:31 +0000 (16:33 -0700)
committerFacebook Github Bot 7 <facebook-github-bot-7-bot@fb.com>
Mon, 18 Jul 2016 23:38:29 +0000 (16:38 -0700)
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
folly/test/ThreadNameTest.cpp

index 1f745e7702f83d2ef89831f1fe827454881157e2..333a329d8e6c4e30108d74c64c06e5da53b3420b 100644 (file)
@@ -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);
 }
index d85ef2c431d2112062b909798c1158d3a3bfe545..ec59687ad543d2ba748e196fb517abe8ce0d6a58 100644 (file)
 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"));
 }