[PATCH] D147361: [Support] Use newer thread naming API if available on Windows.

Scott Todd via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 31 15:52:15 PDT 2023


scotttodd created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
scotttodd requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

See https://learn.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code. The newer API allows for performance analysis tools (such as Tracy <https://github.com/wolfpld/tracy>) that don't use the debugger API to still view thread names.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147361

Files:
  llvm/lib/Support/Windows/Threading.inc


Index: llvm/lib/Support/Windows/Threading.inc
===================================================================
--- llvm/lib/Support/Windows/Threading.inc
+++ llvm/lib/Support/Windows/Threading.inc
@@ -60,7 +60,29 @@
 uint32_t llvm::get_max_thread_name_length() { return 0; }
 
 #if defined(_MSC_VER)
-static void SetThreadName(DWORD Id, LPCSTR Name) {
+static void SetThreadName(DWORD Id, StringRef Name) {
+  // https://learn.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
+
+  // Try first to use the modern SetThreadDescription API.
+  // This will work even if a debugger is not attached meaning that tools that
+  // don't use the debugger API can still query thread names. It's only
+  // available on Win10+.
+  typedef HRESULT(WINAPI * SetThreadDescriptionFn)(HANDLE hThread,
+                                                   PCWSTR lpThreadDescription);
+  SetThreadDescriptionFn ProcSetThreadDescription =
+      (SetThreadDescriptionFn)GetProcAddress(GetModuleHandleW(L"Kernel32.dll"),
+                                             "SetThreadDescription");
+  if (ProcSetThreadDescription) {
+    wchar_t NameWide[16] = {0};
+    MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, Name.data(), -1,
+                        NameWide, 16 - 1);
+    ProcSetThreadDescription(::GetCurrentThread(), NameWide);
+    return;
+  }
+
+  // Fallback to throwing a specially-configured exception. This will only work
+  // if a debugger is attached - thread names will not be available in dumps or
+  // performance analysis tools.
   constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
 
 #pragma pack(push, 8)
@@ -74,7 +96,7 @@
 
   THREADNAME_INFO info;
   info.dwType = 0x1000;
-  info.szName = Name;
+  info.szName = Name.data();
   info.dwThreadId = Id;
   info.dwFlags = 0;
 
@@ -91,7 +113,7 @@
   // Make sure the input is null terminated.
   SmallString<64> Storage;
   StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
-  SetThreadName(::GetCurrentThreadId(), NameStr.data());
+  SetThreadName(::GetCurrentThreadId(), NameStr);
 #endif
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147361.510140.patch
Type: text/x-patch
Size: 2096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230331/4d82d761/attachment.bin>


More information about the llvm-commits mailing list