From feefd3ef4e417bab2fc6c9b276cb4cfc321cfaac Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Thu, 13 Apr 2017 16:01:12 -0500 Subject: [PATCH] swr/rast: name threads to aid debugging Reviewed-by: Bruce Cherniak --- src/gallium/drivers/swr/Makefile.sources | 1 + .../drivers/swr/rasterizer/common/os.cpp | 107 ++++++++++++++++++ .../drivers/swr/rasterizer/common/os.h | 5 +- .../drivers/swr/rasterizer/core/threads.cpp | 15 ++- 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/swr/rasterizer/common/os.cpp diff --git a/src/gallium/drivers/swr/Makefile.sources b/src/gallium/drivers/swr/Makefile.sources index 1afb532434c..056449c2745 100644 --- a/src/gallium/drivers/swr/Makefile.sources +++ b/src/gallium/drivers/swr/Makefile.sources @@ -56,6 +56,7 @@ COMMON_CXX_SOURCES := \ rasterizer/common/formats.cpp \ rasterizer/common/formats.h \ rasterizer/common/isa.hpp \ + rasterizer/common/os.cpp \ rasterizer/common/os.h \ rasterizer/common/rdtsc_buckets.cpp \ rasterizer/common/rdtsc_buckets.h \ diff --git a/src/gallium/drivers/swr/rasterizer/common/os.cpp b/src/gallium/drivers/swr/rasterizer/common/os.cpp new file mode 100644 index 00000000000..295556a5678 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/common/os.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +* Copyright (C) 2017 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +****************************************************************************/ + +#include "common/os.h" + +#if defined(FORCE_LINUX) || defined(__linux__) || defined(__gnu_linux__) +#include +#endif // Linux + + + +#if defined(_WIN32) +static const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void LegacySetThreadName(const char* pThreadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = pThreadName; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; + + if (!IsDebuggerPresent()) + { + // No debugger attached to interpret exception, no need to actually do it + return; + } + +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + } +#pragma warning(pop) +} +#endif // _WIN32 + +void SWR_API SetCurrentThreadName(const char* pThreadName) +{ +#if defined(_WIN32) + // The SetThreadDescription API was brought in version 1607 of Windows 10. + typedef HRESULT(WINAPI* PFNSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription); + // The SetThreadDescription API works even if no debugger is attached. + auto pfnSetThreadDescription = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetThreadDescription")); + + if (!pfnSetThreadDescription) + { + // try KernelBase.dll + pfnSetThreadDescription = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("KernelBase.dll"), "SetThreadDescription")); + } + + if (pfnSetThreadDescription) + { + std::string utf8Name = pThreadName; + std::wstring wideName; + wideName.resize(utf8Name.size() + 1); + swprintf_s(&(wideName.front()), wideName.size(), L"%S", utf8Name.c_str()); + HRESULT hr = pfnSetThreadDescription(GetCurrentThread(), wideName.c_str()); + SWR_ASSERT(SUCCEEDED(hr), "Failed to set thread name to %s", pThreadName); + + // Fall through - it seems like some debuggers only recognize the exception + } + + // Fall back to exception based hack + LegacySetThreadName(pThreadName); +#endif // _WIN32 + +#if defined(FORCE_LINUX) || defined(__linux__) || defined(__gnu_linux__) + pthread_setname_np(pthread_self(), pThreadName); +#endif // Linux +} diff --git a/src/gallium/drivers/swr/rasterizer/common/os.h b/src/gallium/drivers/swr/rasterizer/common/os.h index ef00a255d31..38553df508b 100644 --- a/src/gallium/drivers/swr/rasterizer/common/os.h +++ b/src/gallium/drivers/swr/rasterizer/common/os.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved. +* Copyright (C) 2014-2017 Intel Corporation. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -273,4 +273,7 @@ typedef MEGABYTE GIGABYTE[1024]; #define ATTR_UNUSED #endif +// Defined in os.cpp +void SWR_API SetCurrentThreadName(const char* pThreadName); + #endif//__SWR_OS_H__ diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp index e3ad2585c01..295014d1a7e 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp @@ -747,7 +747,20 @@ DWORD workerThreadMain(LPVOID pData) uint32_t threadId = pThreadData->threadId; uint32_t workerId = pThreadData->workerId; - bindThread(pContext, threadId, pThreadData->procGroupId, pThreadData->forceBindProcGroup); + bindThread(pContext, threadId, pThreadData->procGroupId, pThreadData->forceBindProcGroup); + + { + char threadName[64]; + sprintf_s(threadName, +#if defined(_WIN32) + "SWRWorker_%02d_NUMA%d_Core%02d_T%d", +#else + // linux pthread name limited to 16 chars (including \0) + "w%03d-n%d-c%03d-t%d", +#endif + workerId, pThreadData->numaId, pThreadData->coreId, pThreadData->htId); + SetCurrentThreadName(threadName); + } RDTSC_INIT(threadId); -- 2.30.2