mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-10 10:41:50 +00:00
Implement combining sample callstacks.
This is required, because Windows will send two callstacks with the same timestamp, one for kernel-space, second for user-space.
This commit is contained in:
parent
db1dc311b0
commit
5b642cad01
@ -602,6 +602,7 @@ struct ThreadData
|
|||||||
uint64_t ghostIdx;
|
uint64_t ghostIdx;
|
||||||
#endif
|
#endif
|
||||||
Vector<SampleData> samples;
|
Vector<SampleData> samples;
|
||||||
|
SampleData pendingSample;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpuCtxThreadData
|
struct GpuCtxThreadData
|
||||||
|
@ -3501,6 +3501,7 @@ ThreadData* Worker::NewThread( uint64_t thread )
|
|||||||
#ifndef TRACY_NO_STATISTICS
|
#ifndef TRACY_NO_STATISTICS
|
||||||
td->ghostIdx = 0;
|
td->ghostIdx = 0;
|
||||||
#endif
|
#endif
|
||||||
|
td->pendingSample.time.Clear();
|
||||||
m_data.threads.push_back( td );
|
m_data.threads.push_back( td );
|
||||||
m_threadMap.emplace( thread, td );
|
m_threadMap.emplace( thread, td );
|
||||||
m_data.threadDataLast.first = thread;
|
m_data.threadDataLast.first = thread;
|
||||||
@ -5980,12 +5981,67 @@ void Worker::ProcessCallstackSample( const QueueCallstackSample& ev )
|
|||||||
m_refTimeCtx = refTime;
|
m_refTimeCtx = refTime;
|
||||||
const auto t = TscTime( refTime - m_data.baseTime );
|
const auto t = TscTime( refTime - m_data.baseTime );
|
||||||
|
|
||||||
|
auto& td = *NoticeThread( ev.thread );
|
||||||
|
|
||||||
SampleData sd;
|
SampleData sd;
|
||||||
sd.time.SetVal( t );
|
sd.time.SetVal( t );
|
||||||
sd.callstack.SetVal( callstack );
|
sd.callstack.SetVal( callstack );
|
||||||
|
|
||||||
auto td = NoticeThread( ev.thread );
|
if( m_combineSamples )
|
||||||
ProcessCallstackSampleImpl( sd, *td, t, callstack );
|
{
|
||||||
|
const auto pendingTime = td.pendingSample.time.Val();
|
||||||
|
if( pendingTime == 0 )
|
||||||
|
{
|
||||||
|
td.pendingSample = sd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( pendingTime == t )
|
||||||
|
{
|
||||||
|
const auto& cs1 = GetCallstack( td.pendingSample.callstack.Val() );
|
||||||
|
const auto& cs2 = GetCallstack( callstack );
|
||||||
|
|
||||||
|
const auto sz1 = cs1.size();
|
||||||
|
const auto sz2 = cs2.size();
|
||||||
|
const auto tsz = sz1 + sz2;
|
||||||
|
|
||||||
|
size_t memsize = sizeof( VarArray<CallstackFrameId> ) + tsz * sizeof( CallstackFrameId );
|
||||||
|
auto mem = (char*)m_slab.AllocRaw( memsize );
|
||||||
|
memcpy( mem, cs1.data(), sizeof( CallstackFrameId ) * sz1 );
|
||||||
|
memcpy( mem + sizeof( CallstackFrameId ) * sz1, cs2.data(), sizeof( CallstackFrameId ) * sz2 );
|
||||||
|
|
||||||
|
VarArray<CallstackFrameId>* arr = (VarArray<CallstackFrameId>*)( mem + tsz * sizeof( CallstackFrameId ) );
|
||||||
|
new(arr) VarArray<CallstackFrameId>( tsz, (CallstackFrameId*)mem );
|
||||||
|
|
||||||
|
uint32_t idx;
|
||||||
|
auto it = m_data.callstackMap.find( arr );
|
||||||
|
if( it == m_data.callstackMap.end() )
|
||||||
|
{
|
||||||
|
idx = m_data.callstackPayload.size();
|
||||||
|
m_data.callstackMap.emplace( arr, idx );
|
||||||
|
m_data.callstackPayload.push_back( arr );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idx = it->second;
|
||||||
|
m_slab.Unalloc( memsize );
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.callstack.SetVal( idx );
|
||||||
|
ProcessCallstackSampleImpl( sd, td, pendingTime, idx );
|
||||||
|
td.pendingSample.time.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ProcessCallstackSampleImpl( td.pendingSample, td, pendingTime, td.pendingSample.callstack.Val() );
|
||||||
|
td.pendingSample = sd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ProcessCallstackSampleImpl( sd, td, t, callstack );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::ProcessCallstackFrameSize( const QueueCallstackFrameSize& ev )
|
void Worker::ProcessCallstackFrameSize( const QueueCallstackFrameSize& ev )
|
||||||
|
Loading…
Reference in New Issue
Block a user