// From Xbox documentation typedef struct tagTHREADNAME_INFO { DWORD dwType; // Must be 0x1000 LPCSTR szName; // Pointer to name (in user address space) DWORD dwThreadID; // Thread ID (-1 for caller thread) DWORD dwFlags; // Reserved for future use; must be zero } THREADNAME_INFO; #if (defined _WINDOWS64) || (defined _DURANGO) static bool TrySetThreadDescriptionWin10(DWORD dwThreadID, LPCSTR szThreadName) { typedef HRESULT (WINAPI *SetThreadDescriptionFn)(HANDLE, PCWSTR); static const SetThreadDescriptionFn pfn = []() -> SetThreadDescriptionFn { HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); if (kernel32 == nullptr) return nullptr; return reinterpret_cast( GetProcAddress(kernel32, "SetThreadDescription")); }(); if (pfn == nullptr || szThreadName == nullptr) return false; wchar_t wideName[256] = {}; if (MultiByteToWideChar(CP_UTF8, 0, szThreadName, -1, wideName, 256) == 0) return false; HANDLE thread = (dwThreadID == static_cast(-1)) ? GetCurrentThread() : OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID); if (thread == nullptr) return false; const HRESULT hr = pfn(thread, wideName); if (thread != GetCurrentThread()) CloseHandle(thread); return SUCCEEDED(hr); } #endif void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName ) { #ifndef __PS3__ #if (defined _WINDOWS64) || (defined _DURANGO) if (TrySetThreadDescriptionWin10(dwThreadID, szThreadName)) return; #endif THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; #if ( defined _WINDOWS64 | defined _DURANGO ) #ifdef _MSC_VER // Legacy MSVC debugger thread naming (requires SEH, not C++ exceptions). __try { RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR *)&info); } __except (EXCEPTION_EXECUTE_HANDLER) { } #endif #endif #ifdef _XBOX __try { RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info ); } __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER ) { } #endif #endif // __PS3__ }