summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/platform_thread_mac.mm21
-rw-r--r--base/platform_thread_posix.cc54
2 files changed, 67 insertions, 8 deletions
diff --git a/base/platform_thread_mac.mm b/base/platform_thread_mac.mm
index 46ac241..62139a9 100644
--- a/base/platform_thread_mac.mm
+++ b/base/platform_thread_mac.mm
@@ -5,8 +5,10 @@
#include "base/platform_thread.h"
#import <Foundation/Foundation.h>
+#include <dlfcn.h>
#include "base/logging.h"
+#include "base/safe_strerror_posix.h"
// A simple class that demonstrates our impressive ability to do nothing.
@interface NoOp : NSObject
@@ -45,4 +47,23 @@ void InitThreading() {
}
}
+// static
+void PlatformThread::SetName(const char* name) {
+ // pthread_setname_np is only available in 10.6 or later, so test
+ // for it at runtime.
+ int (*dynamic_pthread_setname_np)(const char*);
+ *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
+ dlsym(RTLD_DEFAULT, "pthread_setname_np");
+ if (!dynamic_pthread_setname_np)
+ return;
+
+ // Mac OS X does not expose the length limit of the name, so
+ // hardcode it.
+ const int kMaxNameLength = 63;
+ std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
+ int err = dynamic_pthread_setname_np(shortened_name.c_str());
+ if (err < 0)
+ LOG(ERROR) << "pthread_setname_np: " << safe_strerror(err);
+}
+
} // namespace base
diff --git a/base/platform_thread_posix.cc b/base/platform_thread_posix.cc
index 16fd529..cc1b209 100644
--- a/base/platform_thread_posix.cc
+++ b/base/platform_thread_posix.cc
@@ -4,6 +4,7 @@
#include "base/platform_thread.h"
+#include <dlfcn.h>
#include <errno.h>
#include <sched.h>
@@ -11,15 +12,21 @@
#include <mach/mach.h>
#include <sys/resource.h>
#include <algorithm>
-#else
+#endif
+
+#if defined(OS_LINUX)
+#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#endif
+#include "base/logging.h"
+#include "base/safe_strerror_posix.h"
+
#if defined(OS_MACOSX)
namespace base {
void InitThreading();
-} // namespace
+} // namespace base
#endif
static void* ThreadFunc(void* closure) {
@@ -63,15 +70,46 @@ void PlatformThread::Sleep(int duration_ms) {
sleep_time = remaining;
}
+#if defined(OS_LINUX)
+// static
+void PlatformThread::SetName(const char* name) {
+ // http://0pointer.de/blog/projects/name-your-threads.html
+
+ // glibc recently added support for pthread_setname_np, but it's not
+ // commonly available yet. So test for it at runtime.
+ int (*dynamic_pthread_setname_np)(pthread_t, const char*);
+ *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
+ dlsym(RTLD_DEFAULT, "pthread_setname_np");
+
+ if (dynamic_pthread_setname_np) {
+ // This limit comes from glibc, which gets it from the kernel
+ // (TASK_COMM_LEN).
+ const int kMaxNameLength = 15;
+ std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
+ int err = dynamic_pthread_setname_np(pthread_self(),
+ shortened_name.c_str());
+ if (err < 0)
+ LOG(ERROR) << "pthread_setname_np: " << safe_strerror(err);
+ } else {
+ // Implementing this function without glibc is simple enough. (We
+ // don't do the name length clipping as above because it will be
+ // truncated by the callee (see TASK_COMM_LEN above).)
+ int err = prctl(PR_SET_NAME, name);
+ if (err < 0)
+ PLOG(ERROR) << "prctl(PR_SET_NAME)";
+ }
+}
+#elif defined(OS_MACOSX)
+// Mac is implemented in platform_thread_mac.mm.
+#else
// static
void PlatformThread::SetName(const char* name) {
- // The POSIX standard does not provide for naming threads, and neither Linux
- // nor Mac OS X (our two POSIX targets) provide any non-portable way of doing
- // it either. (Some BSDs provide pthread_set_name_np but that isn't much of a
- // consolation prize.)
- // TODO(darin): decide whether stuffing the name in TLS or other in-memory
- // structure would be useful for debugging or not.
+ // Leave it unimplemented.
+
+ // (This should be relatively simple to implement for the BSDs; I
+ // just don't have one handy to test the code on.)
}
+#endif // defined(OS_LINUX)
namespace {