diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index 408de413..853e4f6b 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -193,7 +193,7 @@ bool Profiler::SendData( const char* data, size_t len ) bool Profiler::SendString( uint64_t str, const char* ptr, QueueType type ) { - assert( type == QueueType::StringData || type == QueueType::ThreadName || type == QueueType::CustomStringData || type == QueueType::PlotName ); + assert( type == QueueType::StringData || type == QueueType::ThreadName || type == QueueType::CustomStringData || type == QueueType::PlotName || type == QueueType::MessageData ); QueueItem item; item.hdr.type = type; @@ -269,6 +269,10 @@ bool Profiler::HandleServerQuery() case ServerQueryPlotName: SendString( ptr, (const char*)ptr, QueueType::PlotName ); break; + case ServerQueryMessage: + SendString( ptr, (const char*)ptr, QueueType::MessageData ); + delete[] (const char*)ptr; + break; default: assert( false ); break; diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index cea9f5a6..fd4292aa 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -23,6 +23,7 @@ enum ServerQuery : uint8_t ServerQueryCustomString, ServerQuerySourceLocation, ServerQueryPlotName, + ServerQueryMessage, }; enum { WelcomeMessageProgramNameSize = 64 }; diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 7abafc09..54ce7bee 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -24,6 +24,7 @@ enum class QueueType : uint8_t PlotData, PlotName, Message, + MessageData, NUM_TYPES }; @@ -184,6 +185,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueuePlotData ), sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // plot name sizeof( QueueHeader ) + sizeof( QueueMessage ), + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // message data }; static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" ); diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 92e3eb8f..50173622 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -361,7 +361,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 ) + 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 ) { timeval tv; tv.tv_sec = 0; @@ -383,10 +383,14 @@ void View::DispatchProcess( const QueueItem& ev ) { AddThreadString( ev.stringTransfer.ptr, std::string( buf, buf+sz ) ); } - else + else if( ev.hdr.type == QueueType::PlotName ) { HandlePlotName( ev.stringTransfer.ptr, std::string( buf, buf+sz ) ); } + else + { + AddMessageData( ev.stringTransfer.ptr, buf, sz ); + } } else { @@ -397,7 +401,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 ) + 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 ) { uint16_t sz; memcpy( &sz, ptr, sizeof( sz ) ); @@ -414,10 +418,14 @@ void View::DispatchProcess( const QueueItem& ev, const char*& ptr ) { AddThreadString( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) ); } - else + else if( ev.hdr.type == QueueType::PlotName ) { HandlePlotName( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) ); } + else + { + AddMessageData( ev.stringTransfer.ptr, ptr, sz ); + } ptr += sz; } else @@ -472,6 +480,9 @@ void View::Process( const QueueItem& ev ) case QueueType::PlotData: ProcessPlotData( ev.plotData ); break; + case QueueType::Message: + ProcessMessage( ev.message ); + break; default: assert( false ); break; @@ -660,6 +671,12 @@ void View::ProcessPlotData( const QueuePlotData& ev ) } } +void View::ProcessMessage( const QueueMessage& ev ) +{ + m_pendingMessages.emplace( ev.text, MessagePending { int64_t( ev.time * m_timerMul ), ev.thread } ); + ServerQuery( ServerQueryMessage, ev.text ); +} + void View::CheckString( uint64_t ptr ) { if( m_strings.find( ptr ) != m_strings.end() ) return; @@ -753,6 +770,30 @@ void View::AddSourceLocation( const QueueSourceLocation& srcloc ) m_sourceLocation.emplace( srcloc.ptr, srcloc ); } +void View::AddMessageData( uint64_t ptr, const char* str, size_t sz ) +{ + auto txt = new char[sz+1]; + memcpy( txt, str, sz ); + txt[sz] = '\0'; + + auto it = m_pendingMessages.find( ptr ); + assert( it != m_pendingMessages.end() ); + const auto& time = it->second.time; + const auto& thread = it->second.thread; + if( m_messages.empty() || m_messages.back()->time < time ) + { + std::lock_guard lock( m_lock ); + m_messages.push_back( new MessageData { time, txt } ); + } + else + { + auto mit = std::lower_bound( m_messages.begin(), m_messages.end(), time, [] ( const auto& lhs, const auto& rhs ) { return lhs->time < rhs; } ); + std::lock_guard lock( m_lock ); + m_messages.insert( mit, new MessageData { time, txt } ); + } + m_pendingMessages.erase( it ); +} + void View::NewZone( Event* zone, uint64_t thread ) { m_zonesCnt++; diff --git a/server/TracyView.hpp b/server/TracyView.hpp index 1761062b..f9cb7055 100644 --- a/server/TracyView.hpp +++ b/server/TracyView.hpp @@ -77,6 +77,18 @@ private: std::vector data; }; + struct MessagePending + { + int64_t time; + uint64_t thread; + }; + + struct MessageData + { + int64_t time; + const char* txt; + }; + void Worker(); void DispatchProcess( const QueueItem& ev ); @@ -95,6 +107,7 @@ private: void ProcessLockRelease( const QueueLockRelease& ev ); void ProcessLockMark( const QueueLockMark& ev ); void ProcessPlotData( const QueuePlotData& ev ); + void ProcessMessage( const QueueMessage& ev ); void CheckString( uint64_t ptr ); void CheckThreadString( uint64_t id ); @@ -105,6 +118,7 @@ private: void AddThreadString( uint64_t id, std::string&& str ); void AddCustomString( uint64_t ptr, std::string&& str ); void AddSourceLocation( const QueueSourceLocation& srcloc ); + void AddMessageData( uint64_t ptr, const char* str, size_t sz ); void NewZone( Event* zone, uint64_t thread ); void UpdateZone( Event* zone ); @@ -168,6 +182,7 @@ private: Vector m_frames; Vector m_threads; Vector m_plots; + Vector m_messages; std::unordered_map m_strings; std::unordered_map m_threadNames; std::unordered_set m_customStrings; @@ -188,6 +203,7 @@ private: std::unordered_map m_plotMap; std::unordered_map m_plotRev; std::unordered_map m_pendingPlots; + std::unordered_map m_pendingMessages; Slab m_slab;