diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index e59bc60c..cc94360e 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -325,6 +325,33 @@ void Profiler::SendSourceLocation( uint64_t ptr ) s_token.ptr->enqueue( std::move( item ) ); } +bool Profiler::SendSourceLocationPayload( uint64_t _ptr ) +{ + auto ptr = (const char*)_ptr; + + QueueItem item; + item.hdr.type = QueueType::SourceLocationPayload; + item.stringTransfer.ptr = _ptr; + + const auto isz = QueueDataSize[item.hdr.idx]; + + auto buf = m_buffer + m_bufferOffset; + memcpy( buf, &item, isz ); + + const auto len = *((uint32_t*)ptr); + assert( len < TargetFrameSize - isz ); + assert( len <= std::numeric_limits::max() ); + assert( len > 4 ); + const auto l16 = (uint16_t)len - 4; + memcpy( buf + isz, &l16, 2 ); + memcpy( buf + isz + 2, ptr + 4, len - 4 ); + + m_bufferOffset += int( isz + len - 2 ); + if( m_bufferOffset > TargetFrameSize * 2 ) m_bufferOffset = 0; + + return SendData( buf, isz + len - 2 ); +} + static bool DontExit() { return false; } bool Profiler::HandleServerQuery() @@ -361,6 +388,10 @@ bool Profiler::HandleServerQuery() case ServerQuerySourceLocation: SendSourceLocation( ptr ); break; + case ServerQuerySourceLocationPayload: + SendSourceLocationPayload( ptr ); + tracy_free( (void*)ptr ); + break; case ServerQueryPlotName: SendString( ptr, (const char*)ptr, QueueType::PlotName ); break; diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index ff8c8abf..8db5253d 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -190,6 +190,7 @@ private: bool SendData( const char* data, size_t len ); bool SendString( uint64_t ptr, const char* str, QueueType type ); void SendSourceLocation( uint64_t ptr ); + bool SendSourceLocationPayload( uint64_t ptr ); bool HandleServerQuery(); diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index 68677eb4..9d430067 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -23,6 +23,7 @@ enum ServerQuery : uint8_t ServerQueryThreadString, ServerQueryCustomString, ServerQuerySourceLocation, + ServerQuerySourceLocationPayload, ServerQueryPlotName, ServerQueryMessage, }; diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index dde53723..c0fa55f3 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -17,6 +17,7 @@ enum class QueueType : uint8_t CustomStringData, FrameMarkMsg, SourceLocation, + SourceLocationPayload, ZoneText, ZoneName, LockWait, @@ -181,6 +182,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // custom string data sizeof( QueueHeader ) + sizeof( QueueFrameMark ), sizeof( QueueHeader ) + sizeof( QueueSourceLocation ), + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload sizeof( QueueHeader ) + sizeof( QueueZoneText ), sizeof( QueueHeader ) + sizeof( QueueZoneName ), sizeof( QueueHeader ) + sizeof( QueueLockWait ), diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 6001d875..a6b3a580 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -520,7 +520,7 @@ close: void View::DispatchProcess( const QueueItem& ev ) { - if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName || ev.hdr.type == QueueType::MessageData ) + if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName || ev.hdr.type == QueueType::MessageData || ev.hdr.type == QueueType::SourceLocationPayload ) { timeval tv; tv.tv_sec = 0; @@ -547,6 +547,9 @@ void View::DispatchProcess( const QueueItem& ev ) case QueueType::MessageData: AddMessageData( ev.stringTransfer.ptr, buf, sz ); break; + case QueueType::SourceLocationPayload: + AddSourceLocationPayload( ev.stringTransfer.ptr, buf, sz ); + break; default: assert( false ); break; @@ -561,7 +564,7 @@ void View::DispatchProcess( const QueueItem& ev ) void View::DispatchProcess( const QueueItem& ev, const char*& ptr ) { ptr += QueueDataSize[ev.hdr.idx]; - if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName || ev.hdr.type == QueueType::MessageData ) + if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName || ev.hdr.type == QueueType::MessageData || ev.hdr.type == QueueType::SourceLocationPayload ) { uint16_t sz; memcpy( &sz, ptr, sizeof( sz ) ); @@ -583,6 +586,9 @@ void View::DispatchProcess( const QueueItem& ev, const char*& ptr ) case QueueType::MessageData: AddMessageData( ev.stringTransfer.ptr, ptr, sz ); break; + case QueueType::SourceLocationPayload: + AddSourceLocationPayload( ev.stringTransfer.ptr, ptr, sz ); + break; default: assert( false ); break; @@ -682,16 +688,15 @@ void View::ProcessZoneBeginAllocSrcLoc( const QueueZoneBegin& ev ) { auto zone = m_slab.AllocInit(); - //CheckSourceLocation( ev.srcloc ); - zone->start = ev.time * m_timerMul; zone->end = -1; - //zone->srcloc = ShrinkSourceLocation( ev.srcloc ); zone->srcloc = 0; assert( ev.cpu == 0xFFFFFFFF || ev.cpu <= std::numeric_limits::max() ); zone->cpu_start = ev.cpu == 0xFFFFFFFF ? -1 : (int8_t)ev.cpu; zone->text = -1; + CheckSourceLocationPayload( ev.srcloc, zone ); + std::unique_lock lock( m_lock ); NewZone( zone, ev.thread ); lock.unlock(); @@ -917,6 +922,14 @@ void View::CheckSourceLocation( uint64_t ptr ) ServerQuery( ServerQuerySourceLocation, ptr ); } +void View::CheckSourceLocationPayload( uint64_t ptr, ZoneEvent* dst ) +{ + assert( m_pendingSourceLocationPayload.find( ptr ) == m_pendingSourceLocationPayload.end() ); + m_pendingSourceLocationPayload.emplace( ptr, dst ); + + ServerQuery( ServerQuerySourceLocationPayload, ptr ); +} + void View::AddString( uint64_t ptr, std::string&& str ) { assert( m_strings.find( ptr ) == m_strings.end() ); @@ -972,6 +985,33 @@ void View::AddSourceLocation( const QueueSourceLocation& srcloc ) m_sourceLocation.emplace( srcloc.ptr, srcloc ); } +void View::AddSourceLocationPayload( uint64_t ptr, const char* data, size_t sz ) +{ + const auto start = data; + + auto pit = m_pendingSourceLocationPayload.find( ptr ); + assert( pit != m_pendingSourceLocationPayload.end() ); + + uint32_t color, line; + memcpy( &color, data, 4 ); + memcpy( &line, data + 4, 4 ); + data += 8; + auto end = data; + while( *end ) end++; + end++; + char* func = m_slab.Alloc( end - data ); + memcpy( func, data, end - data ); + const auto ssz = sz - ( end - start ); + char* source = m_slab.Alloc( ssz+1 ); + memcpy( source, end, ssz ); + source[ssz] = '\0'; + + std::unique_lock lock( m_lock ); + + lock.unlock(); + m_pendingSourceLocationPayload.erase( ptr ); +} + void View::AddMessageData( uint64_t ptr, const char* str, size_t sz ) { auto txt = m_slab.Alloc( sz+1 ); diff --git a/server/TracyView.hpp b/server/TracyView.hpp index 8f29c86a..b9ae0d0c 100644 --- a/server/TracyView.hpp +++ b/server/TracyView.hpp @@ -141,11 +141,13 @@ private: void CheckThreadString( uint64_t id ); void CheckCustomString( uint64_t ptr, ZoneEvent* dst ); void CheckSourceLocation( uint64_t ptr ); + void CheckSourceLocationPayload( uint64_t ptr, ZoneEvent* dst ); void AddString( uint64_t ptr, std::string&& str ); void AddThreadString( uint64_t id, std::string&& str ); void AddCustomString( uint64_t ptr, std::string&& str ); void AddSourceLocation( const QueueSourceLocation& srcloc ); + void AddSourceLocationPayload( uint64_t ptr, const char* data, size_t sz ); void AddMessageData( uint64_t ptr, const char* str, size_t sz ); uint32_t ShrinkSourceLocation( uint64_t srcloc ); @@ -248,6 +250,7 @@ private: std::unordered_map m_pendingPlots; std::unordered_map m_pendingMessages; std::unordered_map m_sourceLocationShrink; + std::unordered_map m_pendingSourceLocationPayload; Slab<64*1024*1024> m_slab;