Core/Thread: Make use of SetThreadDescription if possible (win32)

This commit is contained in:
Lynix 2020-01-06 15:35:48 +01:00
parent c378ad26a9
commit c73d08af9b
3 changed files with 29 additions and 11 deletions

View File

@ -215,6 +215,7 @@ Nazara Engine:
- Added EmptyStream class, useful to measure how many bytes some writing operations will take - Added EmptyStream class, useful to measure how many bytes some writing operations will take
- SegmentCollider2D: Add support for neighbors (aka "ghost vertices"), allowing to prevent seams collisions - SegmentCollider2D: Add support for neighbors (aka "ghost vertices"), allowing to prevent seams collisions
- ⚠ OBJLoader flips UV by default, fixing a lot of models UV - ⚠ OBJLoader flips UV by default, fixing a lot of models UV
- On Windows, Thread::Set(Current)Name now uses `SetThreadDescription` Win32 function if possible instead of triggering a debugger exception. MinGW builds will use this if available too.
Nazara Development Kit: Nazara Development Kit:
- Added ImageWidget (#139) - Added ImageWidget (#139)

View File

@ -11,6 +11,9 @@
namespace Nz namespace Nz
{ {
// Windows 10, version 1607 brought SetThreadDescription in order to name a thread
using SetThreadDescriptionFunc = HRESULT(WINAPI*)(HANDLE hThread, PCWSTR lpThreadDescription);
#ifdef NAZARA_COMPILER_MSVC #ifdef NAZARA_COMPILER_MSVC
namespace namespace
{ {
@ -50,12 +53,12 @@ namespace Nz
void ThreadImpl::SetName(const Nz::String& name) void ThreadImpl::SetName(const Nz::String& name)
{ {
SetThreadName(m_threadId, name.GetConstBuffer()); SetThreadName(m_handle, name);
} }
void ThreadImpl::SetCurrentName(const Nz::String& name) void ThreadImpl::SetCurrentName(const Nz::String& name)
{ {
SetThreadName(::GetCurrentThreadId(), name.GetConstBuffer()); SetThreadName(::GetCurrentThread(), name);
} }
void ThreadImpl::Sleep(UInt32 time) void ThreadImpl::Sleep(UInt32 time)
@ -63,9 +66,12 @@ namespace Nz
::Sleep(time); ::Sleep(time);
} }
void ThreadImpl::SetThreadName(DWORD threadId, const char* threadName) void ThreadImpl::RaiseThreadNameException(DWORD threadId, const char* threadName)
{ {
#ifdef NAZARA_COMPILER_MSVC #ifdef NAZARA_COMPILER_MSVC
if (!::IsDebuggerPresent())
return;
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
constexpr DWORD MS_VC_EXCEPTION = 0x406D1388; constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
@ -75,8 +81,8 @@ namespace Nz
info.dwThreadID = threadId; info.dwThreadID = threadId;
info.dwFlags = 0; info.dwFlags = 0;
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 6320 6322) #pragma warning(disable: 6320 6322)
__try __try
{ {
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info)); RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
@ -84,10 +90,20 @@ namespace Nz
__except (EXCEPTION_EXECUTE_HANDLER) __except (EXCEPTION_EXECUTE_HANDLER)
{ {
} }
#pragma warning(pop) #pragma warning(pop)
#else #else
NazaraWarning("SetThreadName on Windows is only supported with MSVC for now"); NazaraWarning("SetThreadDescription is not supported and threadname exception is only supported with MSVC");
#endif #endif
}
void ThreadImpl::SetThreadName(HANDLE threadHandle, const Nz::String& name)
{
// Try to use SetThreadDescription if available
static SetThreadDescriptionFunc SetThreadDescription = reinterpret_cast<SetThreadDescriptionFunc>(::GetProcAddress(::GetModuleHandleW(L"Kernel32.dll"), "SetThreadDescription"));
if (SetThreadDescription)
SetThreadDescription(threadHandle, name.GetWideString().data());
else
RaiseThreadNameException(::GetThreadId(threadHandle), name.GetConstBuffer());
} }
unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata) unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata)

View File

@ -30,7 +30,8 @@ namespace Nz
static void Sleep(UInt32 time); static void Sleep(UInt32 time);
private: private:
static void SetThreadName(DWORD threadId, const char* threadName); static void RaiseThreadNameException(DWORD threadId, const char* threadName);
static void SetThreadName(HANDLE threadHandle, const Nz::String& name);
static unsigned int __stdcall ThreadProc(void* userdata); static unsigned int __stdcall ThreadProc(void* userdata);
DWORD m_threadId; DWORD m_threadId;