From a769dff1d07eadfbf26d3f18043aa3ecdfc97482 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Sat, 22 Aug 2020 01:51:51 -0700 Subject: [PATCH 1/2] windows: additionally set thread name via SetThreadDescription --- Source/Core/Common/Thread.cpp | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Source/Core/Common/Thread.cpp b/Source/Core/Common/Thread.cpp index fa81314795..d9503c784e 100644 --- a/Source/Core/Common/Thread.cpp +++ b/Source/Core/Common/Thread.cpp @@ -5,9 +5,11 @@ #include "Common/Thread.h" #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" +#include "Common/StringUtil.h" #ifdef _WIN32 -#include +#include +#include #else #include #endif @@ -64,7 +66,7 @@ void SwitchCurrentThread() // Sets the debugger-visible name of the current thread. // Uses trick documented in: // https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code -void SetCurrentThreadName(const char* szThreadName) +static void SetCurrentThreadNameViaException(const char* name) { static const DWORD MS_VC_EXCEPTION = 0x406D1388; @@ -79,7 +81,7 @@ void SetCurrentThreadName(const char* szThreadName) #pragma pack(pop) info.dwType = 0x1000; - info.szName = szThreadName; + info.szName = name; info.dwThreadID = static_cast(-1); info.dwFlags = 0; @@ -92,6 +94,25 @@ void SetCurrentThreadName(const char* szThreadName) } } +static void SetCurrentThreadNameViaApi(const char* name) +{ + // If possible, also set via the newer API. On some versions of Server it needs to be manually + // resolved. This API allows being able to observe the thread name even if a debugger wasn't + // attached when the name was set (see above link for more info). + static auto pSetThreadDescription = (decltype(&SetThreadDescription))GetProcAddress( + GetModuleHandleA("kernel32"), "SetThreadDescription"); + if (pSetThreadDescription) + { + pSetThreadDescription(GetCurrentThread(), UTF8ToWString(name).c_str()); + } +} + +void SetCurrentThreadName(const char* name) +{ + SetCurrentThreadNameViaException(name); + SetCurrentThreadNameViaApi(name); +} + #else // !WIN32, so must be POSIX threads void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) @@ -129,22 +150,22 @@ void SwitchCurrentThread() usleep(1000 * 1); } -void SetCurrentThreadName(const char* szThreadName) +void SetCurrentThreadName(const char* name) { #ifdef __APPLE__ - pthread_setname_np(szThreadName); + pthread_setname_np(name); #elif defined __FreeBSD__ || defined __OpenBSD__ - pthread_set_name_np(pthread_self(), szThreadName); + pthread_set_name_np(pthread_self(), name); #elif defined __HAIKU__ - rename_thread(find_thread(nullptr), szThreadName); + rename_thread(find_thread(nullptr), name); #else // linux doesn't allow to set more than 16 bytes, including \0. - pthread_setname_np(pthread_self(), std::string(szThreadName).substr(0, 15).c_str()); + pthread_setname_np(pthread_self(), std::string(name).substr(0, 15).c_str()); #endif #ifdef USE_VTUNE // VTune uses OS thread names by default but probably supports longer names when set via its own // API. - __itt_thread_set_name(szThreadName); + __itt_thread_set_name(name); #endif } From 6ef9d7070168559c9a3140dc5aa40913009a13b7 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Sat, 22 Aug 2020 02:55:31 -0700 Subject: [PATCH 2/2] name some threads --- Source/Core/Common/WorkQueueThread.h | 3 +++ Source/Core/DolphinQt/DiscordHandler.cpp | 2 ++ Source/Core/DolphinQt/HotkeyScheduler.cpp | 2 ++ Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp | 3 +++ Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp | 3 +++ Source/Core/VideoCommon/AsyncShaderCompiler.cpp | 3 +++ 6 files changed, 16 insertions(+) diff --git a/Source/Core/Common/WorkQueueThread.h b/Source/Core/Common/WorkQueueThread.h index e5dfac8b49..c0a437c168 100644 --- a/Source/Core/Common/WorkQueueThread.h +++ b/Source/Core/Common/WorkQueueThread.h @@ -10,6 +10,7 @@ #include "Common/Event.h" #include "Common/Flag.h" +#include "Common/Thread.h" // A thread that executes the given function for every item placed into its queue. @@ -53,6 +54,8 @@ private: void ThreadLoop() { + Common::SetCurrentThreadName("WorkQueueThread"); + while (true) { m_wakeup.Wait(); diff --git a/Source/Core/DolphinQt/DiscordHandler.cpp b/Source/Core/DolphinQt/DiscordHandler.cpp index ee90692b35..d083814dce 100644 --- a/Source/Core/DolphinQt/DiscordHandler.cpp +++ b/Source/Core/DolphinQt/DiscordHandler.cpp @@ -69,6 +69,8 @@ void DiscordHandler::ShowNewJoinRequest(const std::string& id, const std::string void DiscordHandler::Run() { + Common::SetCurrentThreadName("DiscordHandler"); + while (!m_stop_requested.IsSet()) { Discord::CallPendingCallbacks(); diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index ec87f5a3fd..190c3a0914 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -134,6 +134,8 @@ static void HandleFrameStepHotkeys() void HotkeyScheduler::Run() { + Common::SetCurrentThreadName("HotkeyScheduler"); + while (!m_stop_requested.IsSet()) { Common::SleepCurrentThread(1000 / 60); diff --git a/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp b/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp index 62febb4c56..76124a97e8 100644 --- a/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp @@ -13,6 +13,7 @@ #include "Common/Event.h" #include "Common/Logging/Log.h" #include "Common/ScopeGuard.h" +#include "Common/Thread.h" #include "InputCommon/ControllerInterface/DInput/DInput.h" #include "InputCommon/ControllerInterface/XInput/XInput.h" @@ -43,6 +44,8 @@ void ciface::Win32::Init(void* hwnd) std::promise message_window_promise; s_thread = std::thread([&message_window_promise] { + Common::SetCurrentThreadName("ciface::Win32 Message Loop"); + HWND message_window = nullptr; Common::ScopeGuard promise_guard([&] { message_window_promise.set_value(message_window); }); diff --git a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp index e51831455e..5c384f6045 100644 --- a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp @@ -9,6 +9,7 @@ #include "Common/Assert.h" #include "Common/MsgHandler.h" +#include "Common/Thread.h" #include "VideoBackends/Vulkan/VulkanContext.h" @@ -185,6 +186,8 @@ bool CommandBufferManager::CreateSubmitThread() { m_submit_loop = std::make_unique(); m_submit_thread = std::thread([this]() { + Common::SetCurrentThreadName("Vulkan CommandBufferManager SubmitThread"); + m_submit_loop->Run([this]() { PendingCommandBufferSubmit submit; { diff --git a/Source/Core/VideoCommon/AsyncShaderCompiler.cpp b/Source/Core/VideoCommon/AsyncShaderCompiler.cpp index 942f293f1b..1586c7d209 100644 --- a/Source/Core/VideoCommon/AsyncShaderCompiler.cpp +++ b/Source/Core/VideoCommon/AsyncShaderCompiler.cpp @@ -6,6 +6,7 @@ #include #include "Common/Assert.h" #include "Common/Logging/Log.h" +#include "Common/Thread.h" namespace VideoCommon { @@ -192,6 +193,8 @@ void AsyncShaderCompiler::WorkerThreadExit(void* param) void AsyncShaderCompiler::WorkerThreadEntryPoint(void* param) { + Common::SetCurrentThreadName("AsyncShaderCompiler Worker"); + // Initialize worker thread with backend-specific method. if (!WorkerThreadInitWorkerThread(param)) {