diff --git a/src/thread/thread.h b/src/thread/thread.h index dddd26f63f..28c8b59988 100644 --- a/src/thread/thread.h +++ b/src/thread/thread.h @@ -133,4 +133,12 @@ void SetSelfAsMainThread(); */ bool IsMainThread(); +/** + * Get the name of the current thread, if any. + * @param str The start of the buffer. + * @param last The last char of the buffer. + * @return Number of chars written to str. + */ +int GetThreadName(char *str, const char *last); + #endif /* THREAD_H */ diff --git a/src/thread/thread_morphos.cpp b/src/thread/thread_morphos.cpp index 9b2485bffe..322a2ab534 100644 --- a/src/thread/thread_morphos.cpp +++ b/src/thread/thread_morphos.cpp @@ -199,3 +199,5 @@ private: void SetSelfAsMainThread() { } bool IsMainThread() { return false; } + +int GetThreadName(char *str, const char *last) { return 0; } diff --git a/src/thread/thread_none.cpp b/src/thread/thread_none.cpp index b68b372f77..30f1adeb6a 100644 --- a/src/thread/thread_none.cpp +++ b/src/thread/thread_none.cpp @@ -37,3 +37,5 @@ public: void SetSelfAsMainThread() { } bool IsMainThread() { return true; } + +int GetThreadName(char *str, const char *last) { return 0; } diff --git a/src/thread/thread_os2.cpp b/src/thread/thread_os2.cpp index 6cb182bae7..c666bbced7 100644 --- a/src/thread/thread_os2.cpp +++ b/src/thread/thread_os2.cpp @@ -149,3 +149,5 @@ public: void SetSelfAsMainThread() { } bool IsMainThread() { return false; } + +int GetThreadName(char *str, const char *last) { return 0; } diff --git a/src/thread/thread_pthread.cpp b/src/thread/thread_pthread.cpp index 103465c0a7..f00ae0bb8f 100644 --- a/src/thread/thread_pthread.cpp +++ b/src/thread/thread_pthread.cpp @@ -11,6 +11,7 @@ #include "../stdafx.h" #include "thread.h" +#include "../string_func.h" #include #include @@ -201,3 +202,17 @@ bool IsMainThread() { return main_thread == pthread_self(); } + +int GetThreadName(char *str, const char *last) +{ +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 12) + char buffer[16]; + int result = pthread_getname_np(pthread_self(), buffer, sizeof(buffer)); + if (result == 0) { + return seprintf(str, last, "%s", buffer); + } +#endif +#endif + return 0; +} diff --git a/src/thread/thread_win32.cpp b/src/thread/thread_win32.cpp index 446c1bafc7..c7e13a775b 100644 --- a/src/thread/thread_win32.cpp +++ b/src/thread/thread_win32.cpp @@ -13,13 +13,19 @@ #include "thread.h" #include "../debug.h" #include "../core/alloc_func.hpp" +#include "../scope.h" +#include "../string_func.h" #include #include #include #include "../os/windows/win32.h" +#include +#include #include "../safeguards.h" +static void Win32SetThreadName(uint id, const char *name); + /** * Win32 thread version for ThreadObject. */ @@ -46,6 +52,7 @@ public: { this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id); if (this->thread == NULL) return; + Win32SetThreadName(this->id, name); ResumeThread(this->thread); } @@ -177,3 +184,26 @@ bool IsMainThread() { return main_thread_id == GetCurrentThreadId(); } + +static std::map _thread_name_map; +static ThreadMutex_Win32 _thread_name_map_mutex; + +static void Win32SetThreadName(uint id, const char *name) +{ + _thread_name_map_mutex.BeginCritical(); + _thread_name_map[id] = name; + _thread_name_map_mutex.EndCritical(); +} + +int GetThreadName(char *str, const char *last) +{ + _thread_name_map_mutex.BeginCritical(); + auto guard = scope_guard([&]() { + _thread_name_map_mutex.EndCritical(); + }); + auto iter = _thread_name_map.find(GetCurrentThreadId()); + if (iter != _thread_name_map.end()) { + return seprintf(str, last, "%s", iter->second.c_str()); + } + return 0; +}