Core/Thread: Add posibility of setting thread name
This commit is contained in:
parent
4a1a335cee
commit
50a3f78f91
|
|
@ -32,11 +32,13 @@ namespace Nz
|
|||
Id GetId() const;
|
||||
bool IsJoinable() const;
|
||||
void Join();
|
||||
void SetName(const String& name);
|
||||
|
||||
Thread& operator=(const Thread&) = delete;
|
||||
Thread& operator=(Thread&& thread);
|
||||
|
||||
static unsigned int HardwareConcurrency();
|
||||
static void SetCurrentThreadName(const String& name);
|
||||
static void Sleep(UInt32 milliseconds);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -29,13 +29,22 @@ namespace Nz
|
|||
pthread_join(m_handle, nullptr);
|
||||
}
|
||||
|
||||
void* ThreadImpl::ThreadProc(void* userdata)
|
||||
void ThreadImpl::SetName(const Nz::String& name)
|
||||
{
|
||||
Functor* func = static_cast<Functor*>(userdata);
|
||||
func->Run();
|
||||
delete func;
|
||||
#ifdef __GNUC__
|
||||
pthread_setname_np(m_handle, name.GetConstBuffer());
|
||||
#else
|
||||
NazaraWarning("Setting thread name is not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
void ThreadImpl::SetCurrentName(const Nz::String& name)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
pthread_setname_np(pthread_self(), name.GetConstBuffer());
|
||||
#else
|
||||
NazaraWarning("Setting current thread name is not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThreadImpl::Sleep(UInt32 time)
|
||||
|
|
@ -56,4 +65,13 @@ namespace Nz
|
|||
while (r == -1 && errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
void* ThreadImpl::ThreadProc(void* userdata)
|
||||
{
|
||||
Functor* func = static_cast<Functor*>(userdata);
|
||||
func->Run();
|
||||
delete func;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@
|
|||
#define NAZARA_THREADIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -21,7 +26,9 @@ namespace Nz
|
|||
|
||||
void Detach();
|
||||
void Join();
|
||||
void SetName(const Nz::String& name);
|
||||
|
||||
static void SetCurrentName(const Nz::String& name);
|
||||
static void Sleep(UInt32 time);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -117,6 +117,25 @@ namespace Nz
|
|||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Changes the debugging name associated to a thread
|
||||
*
|
||||
* Changes the debugging name associated with a particular thread, and may helps with debugging tools.
|
||||
*
|
||||
* \param name The new name of the thread
|
||||
*
|
||||
* \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator)
|
||||
*
|
||||
* \see SetCurrentThreadName
|
||||
*/
|
||||
void Thread::SetName(const String& name)
|
||||
{
|
||||
NazaraAssert(m_impl, "Invalid thread");
|
||||
NazaraAssert(name.GetSize() < 16, "Thread name is too long");
|
||||
|
||||
m_impl->SetName(name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Moves the other thread into this
|
||||
* \return A reference to this
|
||||
|
|
@ -145,18 +164,35 @@ namespace Nz
|
|||
* \brief Gets the number of simulatenous threads that can run on the same cpu
|
||||
* \return The number of simulatenous threads
|
||||
*/
|
||||
|
||||
unsigned int Thread::HardwareConcurrency()
|
||||
{
|
||||
return HardwareInfo::GetProcessorCount();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Changes the debugging name associated to the calling thread
|
||||
*
|
||||
* Changes the debugging name associated with the calling thread, and may helps with debugging tools.
|
||||
*
|
||||
* \param name The new name associated with this thread
|
||||
*
|
||||
* \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator)
|
||||
*
|
||||
* \see SetName
|
||||
*/
|
||||
void Thread::SetCurrentThreadName(const String& name)
|
||||
{
|
||||
NazaraAssert(name.GetSize() < 16, "Thread name is too long");
|
||||
|
||||
ThreadImpl::SetCurrentName(name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Makes sleep this thread
|
||||
*
|
||||
* \param milliseconds The number of milliseconds to sleep
|
||||
*/
|
||||
|
||||
void Thread::Sleep(UInt32 milliseconds)
|
||||
{
|
||||
ThreadImpl::Sleep(milliseconds);
|
||||
|
|
|
|||
|
|
@ -6,13 +6,27 @@
|
|||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Functor.hpp>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
#pragma pack(push,8)
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType;
|
||||
LPCSTR szName;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
ThreadImpl::ThreadImpl(Functor* functor)
|
||||
{
|
||||
m_handle = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, &ThreadImpl::ThreadProc, functor, 0, nullptr));
|
||||
m_handle = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, &ThreadImpl::ThreadProc, functor, 0, &m_threadId));
|
||||
if (!m_handle)
|
||||
NazaraInternalError("Failed to create thread: " + Error::GetLastSystemError());
|
||||
}
|
||||
|
|
@ -29,6 +43,44 @@ namespace Nz
|
|||
CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
void ThreadImpl::SetName(const Nz::String& name)
|
||||
{
|
||||
SetThreadName(m_threadId, name.GetConstBuffer());
|
||||
}
|
||||
|
||||
void ThreadImpl::SetCurrentName(const Nz::String& name)
|
||||
{
|
||||
SetThreadName(::GetCurrentThreadId(), name.GetConstBuffer());
|
||||
}
|
||||
|
||||
void ThreadImpl::Sleep(UInt32 time)
|
||||
{
|
||||
::Sleep(time);
|
||||
}
|
||||
|
||||
void ThreadImpl::SetThreadName(DWORD threadId, const char* threadName)
|
||||
{
|
||||
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
||||
constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName;
|
||||
info.dwThreadID = threadId;
|
||||
info.dwFlags = 0;
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6320 6322)
|
||||
__try
|
||||
{
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
#pragma warning(pop)
|
||||
}
|
||||
|
||||
unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata)
|
||||
{
|
||||
Functor* func = static_cast<Functor*>(userdata);
|
||||
|
|
@ -42,9 +94,4 @@ namespace Nz
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ThreadImpl::Sleep(UInt32 time)
|
||||
{
|
||||
::Sleep(time);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#define NAZARA_THREADIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -23,12 +24,16 @@ namespace Nz
|
|||
|
||||
void Detach();
|
||||
void Join();
|
||||
void SetName(const Nz::String& name);
|
||||
|
||||
static void SetCurrentName(const Nz::String& name);
|
||||
static void Sleep(UInt32 time);
|
||||
|
||||
private:
|
||||
static void SetThreadName(DWORD threadId, const char* threadName);
|
||||
static unsigned int __stdcall ThreadProc(void* userdata);
|
||||
|
||||
DWORD m_threadId;
|
||||
HANDLE m_handle;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue