diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index 23a8722e..c8163922 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -1852,7 +1852,13 @@ bool Profiler::SendData( const char* data, size_t len ) void Profiler::SendString( uint64_t str, const char* ptr, QueueType type ) { - assert( type == QueueType::StringData || type == QueueType::ThreadName || type == QueueType::CustomStringData || type == QueueType::PlotName || type == QueueType::FrameName || type == QueueType::ExternalName ); + assert( type == QueueType::StringData || + type == QueueType::ThreadName || + type == QueueType::CustomStringData || + type == QueueType::PlotName || + type == QueueType::FrameName || + type == QueueType::ExternalName || + type == QueueType::ExternalThreadName ); QueueItem item; MemWrite( &item.hdr.type, type ); diff --git a/client/TracySysTrace.cpp b/client/TracySysTrace.cpp index f26f92f5..44df0f46 100644 --- a/client/TracySysTrace.cpp +++ b/client/TracySysTrace.cpp @@ -158,9 +158,24 @@ void SysTraceWorker( void* ptr ) void SysTraceSendExternalName( uint64_t thread ) { + bool threadSent = false; const auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, thread ); if( hnd != INVALID_HANDLE_VALUE ) { +#if defined NTDDI_WIN10_RS2 && NTDDI_VERSION >= NTDDI_WIN10_RS2 + PWSTR tmp; + GetThreadDescription( hnd, &tmp ); + char buf[256]; + if( tmp ) + { + auto ret = wcstombs( buf, tmp, 256 ); + if( ret != 0 ) + { + GetProfiler().SendString( thread, buf, QueueType::ExternalThreadName ); + threadSent = true; + } + } +#endif const auto pid = GetProcessIdOfThread( hnd ); CloseHandle( hnd ); if( pid != 0 ) @@ -173,6 +188,10 @@ void SysTraceSendExternalName( uint64_t thread ) CloseHandle( phnd ); if( sz != 0 ) { + if( !threadSent ) + { + GetProfiler().SendString( thread, "???", QueueType::ExternalThreadName ); + } auto ptr = buf + sz - 1; while( ptr > buf && *ptr != '\\' ) ptr--; if( *ptr == '\\' ) ptr++; @@ -183,6 +202,7 @@ void SysTraceSendExternalName( uint64_t thread ) } } + GetProfiler().SendString( thread, "???", QueueType::ExternalThreadName ); GetProfiler().SendString( thread, "???", QueueType::ExternalName ); } @@ -374,6 +394,7 @@ void SysTraceWorker( void* ptr ) void SysTraceSendExternalName( uint64_t thread ) { // TODO + GetProfiler().SendString( thread, "???", QueueType::ExternalThreadName ); GetProfiler().SendString( thread, "???", QueueType::ExternalName ); } diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 9ca10373..e999bd5e 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -67,6 +67,7 @@ enum class QueueType : uint8_t FrameName, FrameImageData, ExternalName, + ExternalThreadName, NUM_TYPES }; @@ -426,6 +427,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name }; static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" ); diff --git a/server/TracyView.cpp b/server/TracyView.cpp index fe4f4ada..e10bc686 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -3972,7 +3972,7 @@ int View::DrawCpuData( int offset, double pxns, const ImVec2& wpos, bool hover, { const auto thread = it->Thread(); const auto local = m_worker.IsThreadLocal( thread ); - auto txt = local ? m_worker.GetThreadString( thread ) : m_worker.GetExternalName( thread ); + auto txt = local ? m_worker.GetThreadString( thread ) : m_worker.GetExternalName( thread ).first; const bool untracked = !local && strcmp( txt, m_worker.GetCaptureProgram().c_str() ) == 0; const auto pr0 = ( start - m_zvStart ) * pxns; const auto pr1 = ( end - m_zvStart ) * pxns; @@ -4031,6 +4031,7 @@ int View::DrawCpuData( int offset, double pxns, const ImVec2& wpos, bool hover, { TextDisabledUnformatted( "(external)" ); } + TextFocused( "Thread:", m_worker.GetExternalName( thread ).second ); } ImGui::Separator(); TextFocused( "Start time:", TimeToString( start ) ); diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index c6e26378..91e09eab 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -499,12 +499,14 @@ Worker::Worker( FileRead& f, EventType::Type eventMask ) f.Read( sz ); for( uint64_t i=0; isecond ); + m_data.externalNames.emplace( id, std::make_pair( it->second, it2->second ) ); } } } @@ -1854,12 +1856,12 @@ const SourceLocation& Worker::GetSourceLocation( int16_t srcloc ) const } } -const char* Worker::GetExternalName( uint64_t id ) const +std::pair Worker::GetExternalName( uint64_t id ) const { const auto it = m_data.externalNames.find( id ); if( it == m_data.externalNames.end() ) { - return "???"; + return std::make_pair( "???", "???" ); } else { @@ -2287,6 +2289,9 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr ) case QueueType::ExternalName: AddExternalName( ev.stringTransfer.ptr, ptr, sz ); break; + case QueueType::ExternalThreadName: + AddExternalThreadName( ev.stringTransfer.ptr, ptr, sz ); + break; default: assert( false ); break; @@ -2519,8 +2524,8 @@ void Worker::CheckExternalName( uint64_t id ) { if( m_data.externalNames.find( id ) != m_data.externalNames.end() ) return; - m_data.externalNames.emplace( id, "???" ); - m_pendingExternalNames++; + m_data.externalNames.emplace( id, std::make_pair( "???", "???" ) ); + m_pendingExternalNames += 2; Query( ServerQueryExternalName, id ); } @@ -2622,9 +2627,19 @@ void Worker::AddExternalName( uint64_t ptr, char* str, size_t sz ) assert( m_pendingExternalNames > 0 ); m_pendingExternalNames--; auto it = m_data.externalNames.find( ptr ); - assert( it != m_data.externalNames.end() && strcmp( it->second, "???" ) == 0 ); + assert( it != m_data.externalNames.end() && strcmp( it->second.first, "???" ) == 0 ); const auto sl = StoreString( str, sz ); - it->second = sl.ptr; + it->second.first = sl.ptr; +} + +void Worker::AddExternalThreadName( uint64_t ptr, char* str, size_t sz ) +{ + assert( m_pendingExternalNames > 0 ); + m_pendingExternalNames--; + auto it = m_data.externalNames.find( ptr ); + assert( it != m_data.externalNames.end() && strcmp( it->second.second, "???" ) == 0 ); + const auto sl = StoreString( str, sz ); + it->second.second = sl.ptr; } static const uint8_t DxtcIndexTable[256] = { @@ -4695,7 +4710,9 @@ void Worker::Write( FileWrite& f ) for( auto& v : m_data.externalNames ) { f.Write( &v.first, sizeof( v.first ) ); - uint64_t ptr = (uint64_t)v.second; + uint64_t ptr = (uint64_t)v.second.first; + f.Write( &ptr, sizeof( ptr ) ); + ptr = (uint64_t)v.second.second; f.Write( &ptr, sizeof( ptr ) ); } diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 330fe8e8..606f5b9d 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -173,7 +173,7 @@ private: Vector stringData; flat_hash_map stringMap; flat_hash_map> threadNames; - flat_hash_map> externalNames; + flat_hash_map, nohash> externalNames; flat_hash_map> sourceLocation; Vector sourceLocationPayload; @@ -335,7 +335,7 @@ public: const char* GetThreadString( uint64_t id ) const; bool IsThreadLocal( uint64_t id ) const; const SourceLocation& GetSourceLocation( int16_t srcloc ) const; - const char* GetExternalName( uint64_t id ) const; + std::pair GetExternalName( uint64_t id ) const; const char* GetZoneName( const SourceLocation& srcloc ) const; const char* GetZoneName( const ZoneEvent& ev ) const; @@ -488,6 +488,7 @@ private: void AddThreadString( uint64_t id, char* str, size_t sz ); void AddCustomString( uint64_t ptr, char* str, size_t sz ); void AddExternalName( uint64_t ptr, char* str, size_t sz ); + void AddExternalThreadName( uint64_t ptr, char* str, size_t sz ); void AddFrameImageData( uint64_t ptr, char* data, size_t sz ); tracy_force_inline void AddCallstackPayload( uint64_t ptr, char* data, size_t sz );