From 04ec40f5bcdd3966c1bfac7e64a8bacfdc9671bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonin=20D=C3=A9cimo?= Date: Mon, 21 Oct 2024 13:26:23 +0000 Subject: [PATCH] winpthreads: also use SetThreadDescription to set thread name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using SetThreadDescription has the advantage that on recent Visual Studio / Windows, the thread name is always available regardless of whether a debugger was attached, is also available in crash dumps, and to other tools. Quoting MSDN at Set a thread name in C/C++: https://learn.microsoft.com/en-us/visualstudio/debugger/tips-for-debugging-threads?view=vs-2022&tabs=csharp#set-a-thread-name-in-cc > There are two ways to set a thread name. The first is via the > SetThreadDescription function. The second is by throwing a > particular exception while the Visual Studio debugger is attached to > the process. Each approach has benefits and caveats. The use of > SetThreadDescription is supported starting in Windows 10 version > 1607 or Windows Server 2016. > > It's worth noting that both approaches can be used together, if > desired, since the mechanisms by which they work are independent of > each other. Signed-off-by: Antonin Décimo Signed-off-by: LIU Hao --- mingw-w64-libraries/winpthreads/src/misc.c | 8 ++++++++ mingw-w64-libraries/winpthreads/src/misc.h | 1 + mingw-w64-libraries/winpthreads/src/thread.c | 15 +++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/mingw-w64-libraries/winpthreads/src/misc.c b/mingw-w64-libraries/winpthreads/src/misc.c index b56e8a1b8..c426f59cb 100644 --- a/mingw-w64-libraries/winpthreads/src/misc.c +++ b/mingw-w64-libraries/winpthreads/src/misc.c @@ -26,6 +26,7 @@ void (WINAPI *_pthread_get_system_time_best_as_file_time) (LPFILETIME) = NULL; static ULONGLONG (WINAPI *_pthread_get_tick_count_64) (VOID); +HRESULT (WINAPI *_pthread_set_thread_description) (HANDLE, PCWSTR) = NULL; #if defined(__GNUC__) || defined(__clang__) __attribute__((constructor(0))) @@ -46,6 +47,13 @@ static void winpthreads_init(void) if (!_pthread_get_system_time_best_as_file_time) /* >15ms precision on Windows 10 */ _pthread_get_system_time_best_as_file_time = GetSystemTimeAsFileTime; + + mod = GetModuleHandleA("kernelbase.dll"); + if (mod) + { + _pthread_set_thread_description = + (HRESULT (WINAPI *)(HANDLE, PCWSTR))(void*) GetProcAddress(mod, "SetThreadDescription"); + } } #if defined(_MSC_VER) && !defined(__clang__) diff --git a/mingw-w64-libraries/winpthreads/src/misc.h b/mingw-w64-libraries/winpthreads/src/misc.h index edefb0d54..a853dd085 100644 --- a/mingw-w64-libraries/winpthreads/src/misc.h +++ b/mingw-w64-libraries/winpthreads/src/misc.h @@ -108,6 +108,7 @@ unsigned long _pthread_wait_for_single_object (void *handle, unsigned long timeo unsigned long _pthread_wait_for_multiple_objects (unsigned long count, void **handles, unsigned int all, unsigned long timeout); extern void (WINAPI *_pthread_get_system_time_best_as_file_time) (LPFILETIME); +extern HRESULT (WINAPI *_pthread_set_thread_description) (HANDLE, PCWSTR); #if defined(__GNUC__) || defined(__clang__) #define likely(cond) __builtin_expect((cond) != 0, 1) diff --git a/mingw-w64-libraries/winpthreads/src/thread.c b/mingw-w64-libraries/winpthreads/src/thread.c index 3fc5cedf1..68858cfa6 100644 --- a/mingw-w64-libraries/winpthreads/src/thread.c +++ b/mingw-w64-libraries/winpthreads/src/thread.c @@ -1877,6 +1877,21 @@ pthread_setname_np (pthread_t thread, const char *name) tv->thread_name = stored_name; SetThreadName (tv->tid, name); + + if (_pthread_set_thread_description != NULL) + { + size_t required_size = mbstowcs(NULL, name, 0); + if (required_size != (size_t)-1) + { + wchar_t *wname = malloc((required_size + 1) * sizeof(wchar_t)); + if (wname != NULL) + { + mbstowcs(wname, name, required_size + 1); + _pthread_set_thread_description(tv->h, wname); + free(wname); + } + } + } return 0; }