diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-04-28 17:43:46 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-04-28 17:43:46 -0400 |
commit | 4945cdd909c91b4e155a17a07d6766f9ca88be9f (patch) | |
tree | ab8207abfd31868728ecdffa198133ca55d0904d | |
parent | 858a26bfa16bf0904fe5776e219f8f00b5d864e6 (diff) | |
download | mongo-4945cdd909c91b4e155a17a07d6766f9ca88be9f.tar.gz |
SERVER-15407 Set Thread Name in Windows, Mac OS X, and Linux
(cherry picked from commit cd675c9e3d80f012bbe654d098a988074bd57abc)
-rw-r--r-- | src/mongo/util/concurrency/thread_name.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/mongo/util/concurrency/thread_name.cpp b/src/mongo/util/concurrency/thread_name.cpp index 8b2b66302b6..670494caab8 100644 --- a/src/mongo/util/concurrency/thread_name.cpp +++ b/src/mongo/util/concurrency/thread_name.cpp @@ -25,14 +25,24 @@ * then also delete it in the license file. */ +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kControl + #include "mongo/platform/basic.h" #include "mongo/util/concurrency/thread_name.h" #include <boost/thread/tss.hpp> +#if defined(__APPLE__) || defined(__linux__) +#include <pthread.h> +#endif +#if defined(__APPLE__) +#include <sys/proc_info.h> +#endif + #include "mongo/base/init.h" #include "mongo/platform/atomic_word.h" +#include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" namespace mongo { @@ -41,6 +51,36 @@ using std::string; namespace { +#ifdef _WIN32 +// From https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +// Note: The thread name is only set for the thread if the debugger is attached. + +const DWORD MS_VC_EXCEPTION = 0x406D1388; +#pragma pack(push, 8) +typedef struct tagTHREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void setWindowsThreadName(DWORD dwThreadID, const char* threadName) { + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; +#pragma warning(push) +#pragma warning(disable : 6320 6322) + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } __except (EXCEPTION_EXECUTE_HANDLER) { + } +#pragma warning(pop) +} +#endif + boost::thread_specific_ptr<std::string> threadName; AtomicInt64 nextUnnamedThreadId{1}; @@ -62,6 +102,36 @@ MONGO_INITIALIZER(ThreadNameInitializer)(InitializerContext*) { void setThreadName(StringData name) { invariant(mongoInitializersHaveRun); threadName.reset(new string(name.toString())); + +#if defined(_WIN32) + // Naming should not be expensive compared to thread creation and connection set up, but if + // testing shows otherwise we should make this depend on DEBUG again. + setWindowsThreadName(GetCurrentThreadId(), threadName->c_str()); +#elif defined(__APPLE__) + // Maximum thread name length on OS X is MAXTHREADNAMESIZE (64 characters). This assumes + // OS X 10.6 or later. + int error = pthread_setname_np(threadName->substr(0, MAXTHREADNAMESIZE - 1).c_str()); + if (error) { + log() << "Ignoring error from setting thread name: " << errnoWithDescription(error); + } +#elif defined(__linux__) + // Maximum thread name length supported on Linux is 16 including the null terminator. Ideally + // we use short and descriptive thread names that fit: this helps for log readibility as well. + // Since several components set verbose thread names with a uniqifier at the end, we do a split + // truncation of "first7bytes.last7bytes". + int error = 0; + if (threadName->size() > 15) { + std::string shortName = + threadName->substr(0, 7) + '.' + threadName->substr(threadName->size() - 7); + error = pthread_setname_np(pthread_self(), shortName.c_str()); + } else { + error = pthread_setname_np(pthread_self(), threadName->c_str()); + } + + if (error) { + log() << "Ignoring error from setting thread name: " << errnoWithDescription(error); + } +#endif } const string& getThreadName() { |