From 92b6da7cc2a0f8e6d8f6452774957b4f13877089 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Wed, 14 Aug 2019 02:22:45 +0200 Subject: [PATCH] SetThreadName() only works on the current thread. This breaking change is required, because kernel trace facilities use kernel thread ids, which are inaccessible from the pthread_t level. --- NEWS | 1 + client/TracyProfiler.cpp | 6 ++--- client/TracySysTrace.cpp | 2 ++ common/TracySystem.cpp | 47 ++++++---------------------------------- common/TracySystem.hpp | 8 +++---- test/test.cpp | 41 +++++++++++++++-------------------- 6 files changed, 34 insertions(+), 71 deletions(-) diff --git a/NEWS b/NEWS index ef028097..b8efc913 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ v0.6 (xxxx-xx-xx) - Dropped support for pre-v0.4 traces. - Implemented context switch capture on selected platforms. +- API breakage: SetThreadName() now only works on current thread. v0.5 (2019-08-10) ----------------- diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index 2c2c13b7..10853401 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -1137,18 +1137,15 @@ Profiler::Profiler() s_thread = (Thread*)tracy_malloc( sizeof( Thread ) ); new(s_thread) Thread( LaunchWorker, this ); - SetThreadName( s_thread->Handle(), "Tracy Profiler" ); s_compressThread = (Thread*)tracy_malloc( sizeof( Thread ) ); new(s_compressThread) Thread( LaunchCompressWorker, this ); - SetThreadName( s_compressThread->Handle(), "Tracy Profiler DXT1" ); #ifdef TRACY_HAS_SYSTEM_TRACING if( SysTraceStart() ) { s_sysTraceThread = (Thread*)tracy_malloc( sizeof( Thread ) ); new(s_sysTraceThread) Thread( SysTraceWorker, nullptr ); - SetThreadName( s_sysTraceThread->Handle(), "Tracy Profiler system trace" ); } #endif @@ -1235,6 +1232,8 @@ void Profiler::Worker() s_profilerTid = syscall( SYS_gettid ); #endif + SetThreadName( "Tracy Profiler" ); + while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); rpmalloc_thread_initialize(); @@ -1576,6 +1575,7 @@ void Profiler::Worker() void Profiler::CompressWorker() { + SetThreadName( "Tracy Profiler DXT1" ); while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); rpmalloc_thread_initialize(); for(;;) diff --git a/client/TracySysTrace.cpp b/client/TracySysTrace.cpp index 5ba6f8f8..c1329798 100644 --- a/client/TracySysTrace.cpp +++ b/client/TracySysTrace.cpp @@ -13,6 +13,7 @@ # include # include "../common/TracyAlloc.hpp" +# include "../common/TracySystem.hpp" # include "TracyProfiler.hpp" namespace tracy @@ -143,6 +144,7 @@ void SysTraceStop() void SysTraceWorker( void* ptr ) { + SetThreadName( "Tracy Profiler system trace" ); ProcessTrace( &s_traceHandle2, 1, 0, 0 ); ControlTrace( 0, KERNEL_LOGGER_NAME, s_prop, EVENT_TRACE_CONTROL_STOP ); tracy_free( s_prop ); diff --git a/common/TracySystem.cpp b/common/TracySystem.cpp index eb38acbf..09666a6d 100644 --- a/common/TracySystem.cpp +++ b/common/TracySystem.cpp @@ -26,6 +26,7 @@ #endif #include #include +#include #include "TracySystem.hpp" @@ -34,21 +35,6 @@ # include "TracyAlloc.hpp" #endif -#ifdef __CYGWIN__ -class stub1 // verifyable_object -{ -public: - uint32_t x; - virtual ~stub1(); -}; -class stub2 : public stub1 // pthread -{ -public: - HANDLE hnd; - virtual ~stub2(); -}; -#endif - namespace tracy { @@ -63,18 +49,13 @@ TRACY_API std::atomic& GetThreadNameData(); TRACY_API void InitRPMallocThread(); #endif -void SetThreadName( std::thread& thread, const char* name ) -{ - SetThreadName( thread.native_handle(), name ); -} - -void SetThreadName( std::thread::native_handle_type handle, const char* name ) +void SetThreadName( const char* name ) { #if defined _WIN32 && !defined PTW32_VERSION && !defined __WINPTHREADS_VERSION # if defined NTDDI_WIN10_RS2 && NTDDI_VERSION >= NTDDI_WIN10_RS2 wchar_t buf[256]; mbstowcs( buf, name, 256 ); - SetThreadDescription( static_cast( handle ), buf ); + SetThreadDescription( GetCurrentThread(), buf ); # else const DWORD MS_VC_EXCEPTION=0x406D1388; # pragma pack( push, 8 ) @@ -87,7 +68,7 @@ void SetThreadName( std::thread::native_handle_type handle, const char* name ) }; # pragma pack(pop) - DWORD ThreadId = GetThreadId( static_cast( handle ) ); + DWORD ThreadId = GetCurrentThreadId(); THREADNAME_INFO info; info.dwType = 0x1000; info.szName = name; @@ -107,14 +88,14 @@ void SetThreadName( std::thread::native_handle_type handle, const char* name ) const auto sz = strlen( name ); if( sz <= 15 ) { - pthread_setname_np( handle, name ); + pthread_setname_np( pthread_self(), name ); } else { char buf[16]; memcpy( buf, name, 15 ); buf[15] = '\0'; - pthread_setname_np( handle, buf ); + pthread_setname_np( pthread_self(), buf ); } } #endif @@ -126,21 +107,7 @@ void SetThreadName( std::thread::native_handle_type handle, const char* name ) memcpy( buf, name, sz ); buf[sz+1] = '\0'; auto data = (ThreadNameData*)tracy_malloc( sizeof( ThreadNameData ) ); -# ifdef _WIN32 -# if defined PTW32_VERSION - data->id = pthread_getw32threadid_np( static_cast( handle ) ); -# elif defined __WINPTHREADS_VERSION - data->id = GetThreadId( pthread_gethandle( static_cast( handle ) ) ); -# else - data->id = GetThreadId( static_cast( handle ) ); -# endif -# elif defined __APPLE__ - pthread_threadid_np( handle, &data->id ); -# elif defined __CYGWIN__ - data->id = GetThreadId( ((stub2*)handle)->hnd ); -# else - data->id = (uint64_t)handle; -# endif + data->id = detail::GetThreadHandleImpl(); data->name = buf; data->next = GetThreadNameData().load( std::memory_order_relaxed ); while( !GetThreadNameData().compare_exchange_weak( data->next, data, std::memory_order_release, std::memory_order_relaxed ) ) {} diff --git a/common/TracySystem.hpp b/common/TracySystem.hpp index 1d48d9ca..fa0a56e2 100644 --- a/common/TracySystem.hpp +++ b/common/TracySystem.hpp @@ -7,7 +7,7 @@ # endif #endif -#ifdef _WIN32 +#if defined _WIN32 || defined __CYGWIN__ # ifndef _WINDOWS_ extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); # endif @@ -23,7 +23,6 @@ extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void #endif #include -#include #include "TracyApi.h" @@ -34,7 +33,7 @@ namespace detail { static inline uint64_t GetThreadHandleImpl() { -#ifdef _WIN32 +#if defined _WIN32 || defined __CYGWIN__ static_assert( sizeof( decltype( GetCurrentThreadId() ) ) <= sizeof( uint64_t ), "Thread handle too big to fit in protocol" ); return uint64_t( GetCurrentThreadId() ); #elif defined __APPLE__ @@ -61,8 +60,7 @@ static inline uint64_t GetThreadHandle() } #endif -void SetThreadName( std::thread& thread, const char* name ); -void SetThreadName( std::thread::native_handle_type handle, const char* name ); +void SetThreadName( const char* name ); const char* GetThreadName( uint64_t id ); } diff --git a/test/test.cpp b/test/test.cpp index 8620eb04..4f3e1f33 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -36,6 +36,7 @@ void operator delete( void* ptr ) noexcept void TestFunction() { + tracy::SetThreadName( "First/second thread" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -46,6 +47,7 @@ void TestFunction() void ResolutionCheck() { + tracy::SetThreadName( "Resolution check" ); for(;;) { { @@ -62,6 +64,7 @@ void ResolutionCheck() void ScopeCheck() { + tracy::SetThreadName( "Scope check" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -74,6 +77,7 @@ static TracyLockable( std::recursive_mutex, recmutex ); void Lock1() { + tracy::SetThreadName( "Lock 1" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 4 ) ); @@ -86,6 +90,7 @@ void Lock1() void Lock2() { + tracy::SetThreadName( "Lock 2" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 3 ) ); @@ -98,6 +103,7 @@ void Lock2() void Lock3() { + tracy::SetThreadName( "Lock 3" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -110,6 +116,7 @@ void Lock3() void RecLock() { + tracy::SetThreadName( "Recursive mtx 1/2" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 7 ) ); @@ -129,6 +136,7 @@ void RecLock() void Plot() { + tracy::SetThreadName( "Plot 1/2" ); unsigned char i = 0; for(;;) { @@ -142,6 +150,7 @@ void Plot() void MessageTest() { + tracy::SetThreadName( "Message test" ); for(;;) { TracyMessage( "Tock", 4 ); @@ -165,6 +174,7 @@ static int Fibonacci( int n ) void DepthTest() { + tracy::SetThreadName( "Depth test" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) ); @@ -179,6 +189,7 @@ static TracySharedLockable( std::shared_mutex, sharedMutex ); void SharedRead1() { + tracy::SetThreadName( "Shared read 1/2" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -189,6 +200,7 @@ void SharedRead1() void SharedRead2() { + tracy::SetThreadName( "Shared read 3" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 6 ) ); @@ -199,6 +211,7 @@ void SharedRead2() void SharedWrite1() { + tracy::SetThreadName( "Shared write 1" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 3 ) ); @@ -209,6 +222,7 @@ void SharedWrite1() void SharedWrite2() { + tracy::SetThreadName( "Shared write 2" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 5 ) ); @@ -224,6 +238,7 @@ void CaptureCallstack() void CallstackTime() { + tracy::SetThreadName( "Callstack time" ); for(;;) { std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -233,6 +248,7 @@ void CallstackTime() void OnlyMemory() { + tracy::SetThreadName( "Only memory" ); new int; } @@ -241,6 +257,7 @@ static TracyLockable( std::mutex, deadlockMutex2 ); void DeadlockTest1() { + tracy::SetThreadName( "Deadlock test 1" ); deadlockMutex1.lock(); std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); deadlockMutex2.lock(); @@ -248,6 +265,7 @@ void DeadlockTest1() void DeadlockTest2() { + tracy::SetThreadName( "Deadlock test 2" ); deadlockMutex2.lock(); std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); deadlockMutex1.lock(); @@ -278,29 +296,6 @@ int main() auto t21 = std::thread( DeadlockTest1 ); auto t22 = std::thread( DeadlockTest2 ); - tracy::SetThreadName( t1, "First thread" ); - tracy::SetThreadName( t2, "Second thread" ); - tracy::SetThreadName( t3, "Resolution check" ); - tracy::SetThreadName( t4, "Scope check" ); - tracy::SetThreadName( t5, "Lock 1" ); - tracy::SetThreadName( t6, "Lock 2" ); - tracy::SetThreadName( t7, "Lock 3" ); - tracy::SetThreadName( t8, "Plot 1" ); - tracy::SetThreadName( t9, "Plot 2" ); - tracy::SetThreadName( t10, "Message test" ); - tracy::SetThreadName( t11, "Depth test" ); - tracy::SetThreadName( t12, "Recursive mtx 1" ); - tracy::SetThreadName( t13, "Recursive mtx 2" ); - tracy::SetThreadName( t14, "Shared read 1" ); - tracy::SetThreadName( t15, "Shared read 2" ); - tracy::SetThreadName( t16, "Shared read 3" ); - tracy::SetThreadName( t17, "Shared write 1" ); - tracy::SetThreadName( t18, "Shared write 2" ); - tracy::SetThreadName( t19, "Callstack time" ); - tracy::SetThreadName( t20, "Only memory" ); - tracy::SetThreadName( t21, "Deadlock test 1" ); - tracy::SetThreadName( t22, "Deadlock test 2" ); - int x, y; auto image = stbi_load( "image.jpg", &x, &y, nullptr, 4 );