summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 23:26:34 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 23:26:34 +0000
commitfae91273c06d59b20e6654a455c342d8fb72f946 (patch)
tree0de7a578afd145a5d8d4fdb7a8c2eaaea043282c
parent5439283ff95a6f7d8b9e6d86c0fd178b0238acaa (diff)
downloadchromium_src-fae91273c06d59b20e6654a455c342d8fb72f946.zip
chromium_src-fae91273c06d59b20e6654a455c342d8fb72f946.tar.gz
chromium_src-fae91273c06d59b20e6654a455c342d8fb72f946.tar.bz2
posix: set thread names
There's a non-portable function for doing this: pthread_setname_np. It's supported by OS X >= 10.6 and the Xcode debugger will show the thread names if they're provided. On Linux, support has just recently been added to glibc for the same function. Since OS coverage of the function is so spotty, we look for the symbol at runtime; on Linux we fall back to another implementation of the same functionality if the function isn't available. Review URL: http://codereview.chromium.org/2774001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49212 0039d316-1c4b-4281-b951-d872f2087c98
-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 {