mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-27 00:04:35 +00:00
Receive plot data.
This commit is contained in:
parent
cb0011755d
commit
fe0366c792
@ -193,7 +193,7 @@ bool Profiler::SendData( const char* data, size_t len )
|
|||||||
|
|
||||||
bool Profiler::SendString( uint64_t str, const char* ptr, QueueType type )
|
bool Profiler::SendString( uint64_t str, const char* ptr, QueueType type )
|
||||||
{
|
{
|
||||||
assert( type == QueueType::StringData || type == QueueType::ThreadName || type == QueueType::CustomStringData );
|
assert( type == QueueType::StringData || type == QueueType::ThreadName || type == QueueType::CustomStringData || type == QueueType::PlotName );
|
||||||
|
|
||||||
QueueItem item;
|
QueueItem item;
|
||||||
item.hdr.type = type;
|
item.hdr.type = type;
|
||||||
@ -264,6 +264,9 @@ bool Profiler::HandleServerQuery()
|
|||||||
case ServerQuerySourceLocation:
|
case ServerQuerySourceLocation:
|
||||||
SendSourceLocation( ptr );
|
SendSourceLocation( ptr );
|
||||||
break;
|
break;
|
||||||
|
case ServerQueryPlotName:
|
||||||
|
SendString( ptr, (const char*)ptr, QueueType::PlotName );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert( false );
|
assert( false );
|
||||||
break;
|
break;
|
||||||
|
@ -22,6 +22,7 @@ enum ServerQuery : uint8_t
|
|||||||
ServerQueryThreadString,
|
ServerQueryThreadString,
|
||||||
ServerQueryCustomString,
|
ServerQueryCustomString,
|
||||||
ServerQuerySourceLocation,
|
ServerQuerySourceLocation,
|
||||||
|
ServerQueryPlotName,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { WelcomeMessageProgramNameSize = 64 };
|
enum { WelcomeMessageProgramNameSize = 64 };
|
||||||
|
@ -22,6 +22,7 @@ enum class QueueType : uint8_t
|
|||||||
LockRelease,
|
LockRelease,
|
||||||
LockMark,
|
LockMark,
|
||||||
PlotData,
|
PlotData,
|
||||||
|
PlotName,
|
||||||
NUM_TYPES
|
NUM_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -170,6 +171,7 @@ static const size_t QueueDataSize[] = {
|
|||||||
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueLockMark ),
|
sizeof( QueueHeader ) + sizeof( QueueLockMark ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueuePlotData ),
|
sizeof( QueueHeader ) + sizeof( QueuePlotData ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // plot name
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert( sizeof( QueueDataSize ) / sizeof( size_t ) == (uint8_t)QueueType::NUM_TYPES, "QueueDataSize mismatch" );
|
static_assert( sizeof( QueueDataSize ) / sizeof( size_t ) == (uint8_t)QueueType::NUM_TYPES, "QueueDataSize mismatch" );
|
||||||
|
@ -332,7 +332,7 @@ close:
|
|||||||
|
|
||||||
void View::DispatchProcess( const QueueItem& ev )
|
void View::DispatchProcess( const QueueItem& ev )
|
||||||
{
|
{
|
||||||
if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName )
|
if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName )
|
||||||
{
|
{
|
||||||
timeval tv;
|
timeval tv;
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
@ -350,10 +350,14 @@ void View::DispatchProcess( const QueueItem& ev )
|
|||||||
{
|
{
|
||||||
AddString( ev.stringTransfer.ptr, std::string( buf, buf+sz ) );
|
AddString( ev.stringTransfer.ptr, std::string( buf, buf+sz ) );
|
||||||
}
|
}
|
||||||
else
|
else if( ev.hdr.type == QueueType::ThreadName )
|
||||||
{
|
{
|
||||||
AddThreadString( ev.stringTransfer.ptr, std::string( buf, buf+sz ) );
|
AddThreadString( ev.stringTransfer.ptr, std::string( buf, buf+sz ) );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandlePlotName( ev.stringTransfer.ptr, std::string( buf, buf+sz ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -364,7 +368,7 @@ void View::DispatchProcess( const QueueItem& ev )
|
|||||||
void View::DispatchProcess( const QueueItem& ev, const char*& ptr )
|
void View::DispatchProcess( const QueueItem& ev, const char*& ptr )
|
||||||
{
|
{
|
||||||
ptr += QueueDataSize[ev.hdr.idx];
|
ptr += QueueDataSize[ev.hdr.idx];
|
||||||
if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName )
|
if( ev.hdr.type == QueueType::CustomStringData || ev.hdr.type == QueueType::StringData || ev.hdr.type == QueueType::ThreadName || ev.hdr.type == QueueType::PlotName )
|
||||||
{
|
{
|
||||||
uint16_t sz;
|
uint16_t sz;
|
||||||
memcpy( &sz, ptr, sizeof( sz ) );
|
memcpy( &sz, ptr, sizeof( sz ) );
|
||||||
@ -377,10 +381,14 @@ void View::DispatchProcess( const QueueItem& ev, const char*& ptr )
|
|||||||
{
|
{
|
||||||
AddString( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) );
|
AddString( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) );
|
||||||
}
|
}
|
||||||
else
|
else if( ev.hdr.type == QueueType::ThreadName )
|
||||||
{
|
{
|
||||||
AddThreadString( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) );
|
AddThreadString( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandlePlotName( ev.stringTransfer.ptr, std::string( ptr, ptr+sz ) );
|
||||||
|
}
|
||||||
ptr += sz;
|
ptr += sz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -432,6 +440,9 @@ void View::Process( const QueueItem& ev )
|
|||||||
case QueueType::LockMark:
|
case QueueType::LockMark:
|
||||||
ProcessLockMark( ev.lockMark );
|
ProcessLockMark( ev.lockMark );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::PlotData:
|
||||||
|
ProcessPlotData( ev.plotData );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert( false );
|
assert( false );
|
||||||
break;
|
break;
|
||||||
@ -576,6 +587,49 @@ void View::ProcessLockMark( const QueueLockMark& ev )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::ProcessPlotData( const QueuePlotData& ev )
|
||||||
|
{
|
||||||
|
PlotData* plot;
|
||||||
|
auto it = m_plotMap.find( ev.name );
|
||||||
|
if( it == m_plotMap.end() )
|
||||||
|
{
|
||||||
|
auto pit = m_pendingPlots.find( ev.name );
|
||||||
|
if( pit == m_pendingPlots.end() )
|
||||||
|
{
|
||||||
|
plot = m_slab.Alloc<PlotData>();
|
||||||
|
plot->name = ev.name;
|
||||||
|
m_pendingPlots.emplace( ev.name, plot );
|
||||||
|
ServerQuery( ServerQueryPlotName, ev.name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plot = pit->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plot = m_plots[it->second];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto time = int64_t( ev.time * m_timerMul );
|
||||||
|
std::lock_guard<std::mutex> lock( m_lock );
|
||||||
|
switch( ev.type )
|
||||||
|
{
|
||||||
|
case PlotDataType::Double:
|
||||||
|
InsertPlot( plot, time, ev.data.d );
|
||||||
|
break;
|
||||||
|
case PlotDataType::Float:
|
||||||
|
InsertPlot( plot, time, (double)ev.data.f );
|
||||||
|
break;
|
||||||
|
case PlotDataType::Int:
|
||||||
|
InsertPlot( plot, time, (double)ev.data.i );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void View::CheckString( uint64_t ptr )
|
void View::CheckString( uint64_t ptr )
|
||||||
{
|
{
|
||||||
if( m_strings.find( ptr ) != m_strings.end() ) return;
|
if( m_strings.find( ptr ) != m_strings.end() ) return;
|
||||||
@ -788,6 +842,48 @@ void View::UpdateLockCount( LockMap& lockmap, size_t pos )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::InsertPlot( PlotData* plot, int64_t time, double val )
|
||||||
|
{
|
||||||
|
if( plot->data.empty() || plot->data.back().time < time )
|
||||||
|
{
|
||||||
|
plot->data.emplace_back( PlotItem { time, val } );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = std::lower_bound( plot->data.begin(), plot->data.end(), time, [] ( const auto& lhs, const auto& rhs ) { return lhs.time < rhs; } );
|
||||||
|
it = plot->data.insert( it, PlotItem { time, val } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::HandlePlotName( uint64_t name, std::string&& str )
|
||||||
|
{
|
||||||
|
auto pit = m_pendingPlots.find( name );
|
||||||
|
assert( pit != m_pendingPlots.end() );
|
||||||
|
|
||||||
|
auto it = m_plotRev.find( str );
|
||||||
|
if( it == m_plotRev.end() )
|
||||||
|
{
|
||||||
|
const auto idx = m_plots.size();
|
||||||
|
m_plots.push_back( pit->second );
|
||||||
|
m_plotMap.emplace( name, idx );
|
||||||
|
m_plotRev.emplace( str, idx );
|
||||||
|
m_strings.emplace( name, std::move( str ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_plotMap.emplace( name, it->second );
|
||||||
|
const auto& pp = pit->second->data;
|
||||||
|
auto plot = m_plots[it->second];
|
||||||
|
for( auto& v : pp )
|
||||||
|
{
|
||||||
|
InsertPlot( plot, v.time, v.val );
|
||||||
|
}
|
||||||
|
// pit->second is leaked
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pendingPlots.erase( pit );
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t View::GetFrameTime( size_t idx ) const
|
uint64_t View::GetFrameTime( size_t idx ) const
|
||||||
{
|
{
|
||||||
if( idx < m_frames.size() - 1 )
|
if( idx < m_frames.size() - 1 )
|
||||||
|
@ -62,6 +62,18 @@ private:
|
|||||||
bool blocked;
|
bool blocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlotItem
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
double val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlotData
|
||||||
|
{
|
||||||
|
uint64_t name;
|
||||||
|
std::vector<PlotItem> data;
|
||||||
|
};
|
||||||
|
|
||||||
void Worker();
|
void Worker();
|
||||||
|
|
||||||
void DispatchProcess( const QueueItem& ev );
|
void DispatchProcess( const QueueItem& ev );
|
||||||
@ -79,6 +91,7 @@ private:
|
|||||||
void ProcessLockObtain( const QueueLockObtain& ev );
|
void ProcessLockObtain( const QueueLockObtain& ev );
|
||||||
void ProcessLockRelease( const QueueLockRelease& ev );
|
void ProcessLockRelease( const QueueLockRelease& ev );
|
||||||
void ProcessLockMark( const QueueLockMark& ev );
|
void ProcessLockMark( const QueueLockMark& ev );
|
||||||
|
void ProcessPlotData( const QueuePlotData& ev );
|
||||||
|
|
||||||
void CheckString( uint64_t ptr );
|
void CheckString( uint64_t ptr );
|
||||||
void CheckThreadString( uint64_t id );
|
void CheckThreadString( uint64_t id );
|
||||||
@ -98,6 +111,9 @@ private:
|
|||||||
void InsertLockEvent( LockMap& lockmap, LockEvent* lev, uint64_t thread );
|
void InsertLockEvent( LockMap& lockmap, LockEvent* lev, uint64_t thread );
|
||||||
void UpdateLockCount( LockMap& lockmap, size_t pos );
|
void UpdateLockCount( LockMap& lockmap, size_t pos );
|
||||||
|
|
||||||
|
void InsertPlot( PlotData* plot, int64_t time, double val );
|
||||||
|
void HandlePlotName( uint64_t name, std::string&& str );
|
||||||
|
|
||||||
uint64_t GetFrameTime( size_t idx ) const;
|
uint64_t GetFrameTime( size_t idx ) const;
|
||||||
uint64_t GetFrameBegin( size_t idx ) const;
|
uint64_t GetFrameBegin( size_t idx ) const;
|
||||||
uint64_t GetFrameEnd( size_t idx ) const;
|
uint64_t GetFrameEnd( size_t idx ) const;
|
||||||
@ -145,6 +161,7 @@ private:
|
|||||||
std::mutex m_lock;
|
std::mutex m_lock;
|
||||||
Vector<uint64_t> m_frames;
|
Vector<uint64_t> m_frames;
|
||||||
Vector<ThreadData*> m_threads;
|
Vector<ThreadData*> m_threads;
|
||||||
|
Vector<PlotData*> m_plots;
|
||||||
std::unordered_map<uint64_t, std::string> m_strings;
|
std::unordered_map<uint64_t, std::string> m_strings;
|
||||||
std::unordered_map<uint64_t, std::string> m_threadNames;
|
std::unordered_map<uint64_t, std::string> m_threadNames;
|
||||||
std::unordered_set<const char*, charutil::Hasher, charutil::Comparator> m_customStrings;
|
std::unordered_set<const char*, charutil::Hasher, charutil::Comparator> m_customStrings;
|
||||||
@ -162,6 +179,9 @@ private:
|
|||||||
std::unordered_set<uint64_t> m_pendingSourceLocation;
|
std::unordered_set<uint64_t> m_pendingSourceLocation;
|
||||||
std::unordered_map<uint64_t, Event*> m_pendingCustomStrings;
|
std::unordered_map<uint64_t, Event*> m_pendingCustomStrings;
|
||||||
std::unordered_map<uint64_t, uint32_t> m_threadMap;
|
std::unordered_map<uint64_t, uint32_t> m_threadMap;
|
||||||
|
std::unordered_map<uint64_t, uint32_t> m_plotMap;
|
||||||
|
std::unordered_map<std::string, uint32_t> m_plotRev;
|
||||||
|
std::unordered_map<uint64_t, PlotData*> m_pendingPlots;
|
||||||
|
|
||||||
Slab<EventSize*1024*1024> m_slab;
|
Slab<EventSize*1024*1024> m_slab;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user