[Mesa-dev] [PATCH 04/15] swr: [rasterizer core/common] Name threads for debugging

Tim Rowley timothy.o.rowley at intel.com
Tue Apr 25 14:50:29 UTC 2017


---
 src/gallium/drivers/swr/Makefile.sources           |   1 +
 src/gallium/drivers/swr/rasterizer/common/os.cpp   | 107 +++++++++++++++++++++
 src/gallium/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 1afb532..056449c 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 0000000..295556a
--- /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 <pthread.h>
+#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<PFNSetThreadDescription>(
+            GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetThreadDescription"));
+
+    if (!pfnSetThreadDescription)
+    {
+        // try KernelBase.dll
+        pfnSetThreadDescription =
+            reinterpret_cast<PFNSetThreadDescription>(
+                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 ef00a25..38553df 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 e3ad258..295014d 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.7.4



More information about the mesa-dev mailing list