mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-27 00:04:35 +00:00
Sleep if sys trace pipe buffer underruns.
This commit is contained in:
parent
2d50d07438
commit
8f6e94d75c
@ -506,96 +506,145 @@ ssize_t getline(char **buf, size_t *bufsiz, FILE *fp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ProcessTraceLines( FILE* f )
|
static void HandleTraceLine( const char* line )
|
||||||
{
|
{
|
||||||
size_t lsz = 1024;
|
line += 24;
|
||||||
auto line = (char*)malloc( lsz );
|
const auto cpu = (uint8_t)ReadNumber( line );
|
||||||
|
|
||||||
for(;;)
|
line++; // ']'
|
||||||
{
|
while( *line == ' ' ) line++;
|
||||||
auto rd = getline( &line, &lsz, f );
|
|
||||||
if( rd < 0 ) break;
|
|
||||||
|
|
||||||
#ifdef TRACY_ON_DEMAND
|
|
||||||
if( !GetProfiler().IsConnected() ) continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* ptr = line + 24;
|
|
||||||
const auto cpu = (uint8_t)ReadNumber( ptr );
|
|
||||||
|
|
||||||
ptr++; // ']'
|
|
||||||
while( *ptr == ' ' ) ptr++;
|
|
||||||
|
|
||||||
#if defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
|
#if defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
|
||||||
const auto time = ReadNumber( ptr );
|
const auto time = ReadNumber( line );
|
||||||
#elif __ARM_ARCH >= 6
|
#elif __ARM_ARCH >= 6
|
||||||
const auto ts = ReadNumber( ptr );
|
const auto ts = ReadNumber( line );
|
||||||
ptr++; // '.'
|
line++; // '.'
|
||||||
const auto tus = ReadNumber( ptr );
|
const auto tus = ReadNumber( line );
|
||||||
const auto time = ts * 1000000000ll + tus * 1000ll;
|
const auto time = ts * 1000000000ll + tus * 1000ll;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ptr += 2; // ': '
|
line += 2; // ': '
|
||||||
if( memcmp( ptr, "sched_switch", 12 ) == 0 )
|
if( memcmp( line, "sched_switch", 12 ) == 0 )
|
||||||
{
|
{
|
||||||
ptr += 14;
|
line += 14;
|
||||||
|
|
||||||
while( memcmp( ptr, "prev_pid", 8 ) != 0 ) ptr++;
|
while( memcmp( line, "prev_pid", 8 ) != 0 ) line++;
|
||||||
ptr += 9;
|
line += 9;
|
||||||
|
|
||||||
const auto oldPid = ReadNumber( ptr );
|
const auto oldPid = ReadNumber( line );
|
||||||
ptr++;
|
line++;
|
||||||
|
|
||||||
while( memcmp( ptr, "prev_state", 10 ) != 0 ) ptr++;
|
while( memcmp( line, "prev_state", 10 ) != 0 ) line++;
|
||||||
ptr += 11;
|
line += 11;
|
||||||
|
|
||||||
const auto oldState = (uint8_t)ReadState( *ptr );
|
const auto oldState = (uint8_t)ReadState( *line );
|
||||||
ptr += 5;
|
line += 5;
|
||||||
|
|
||||||
while( memcmp( ptr, "next_pid", 8 ) != 0 ) ptr++;
|
while( memcmp( line, "next_pid", 8 ) != 0 ) line++;
|
||||||
ptr += 9;
|
line += 9;
|
||||||
|
|
||||||
const auto newPid = ReadNumber( ptr );
|
const auto newPid = ReadNumber( line );
|
||||||
|
|
||||||
uint8_t reason = 100;
|
uint8_t reason = 100;
|
||||||
|
|
||||||
Magic magic;
|
Magic magic;
|
||||||
auto token = GetToken();
|
auto token = GetToken();
|
||||||
auto& tail = token->get_tail_index();
|
auto& tail = token->get_tail_index();
|
||||||
auto item = token->enqueue_begin( magic );
|
auto item = token->enqueue_begin( magic );
|
||||||
MemWrite( &item->hdr.type, QueueType::ContextSwitch );
|
MemWrite( &item->hdr.type, QueueType::ContextSwitch );
|
||||||
MemWrite( &item->contextSwitch.time, time );
|
MemWrite( &item->contextSwitch.time, time );
|
||||||
MemWrite( &item->contextSwitch.oldThread, oldPid );
|
MemWrite( &item->contextSwitch.oldThread, oldPid );
|
||||||
MemWrite( &item->contextSwitch.newThread, newPid );
|
MemWrite( &item->contextSwitch.newThread, newPid );
|
||||||
MemWrite( &item->contextSwitch.cpu, cpu );
|
MemWrite( &item->contextSwitch.cpu, cpu );
|
||||||
MemWrite( &item->contextSwitch.reason, reason );
|
MemWrite( &item->contextSwitch.reason, reason );
|
||||||
MemWrite( &item->contextSwitch.state, oldState );
|
MemWrite( &item->contextSwitch.state, oldState );
|
||||||
tail.store( magic + 1, std::memory_order_release );
|
tail.store( magic + 1, std::memory_order_release );
|
||||||
}
|
|
||||||
else if( memcmp( ptr, "sched_wakeup", 12 ) == 0 )
|
|
||||||
{
|
|
||||||
ptr += 14;
|
|
||||||
|
|
||||||
while( memcmp( ptr, "pid", 3 ) != 0 ) ptr++;
|
|
||||||
ptr += 4;
|
|
||||||
|
|
||||||
const auto pid = ReadNumber( ptr );
|
|
||||||
|
|
||||||
Magic magic;
|
|
||||||
auto token = GetToken();
|
|
||||||
auto& tail = token->get_tail_index();
|
|
||||||
auto item = token->enqueue_begin( magic );
|
|
||||||
MemWrite( &item->hdr.type, QueueType::ThreadWakeup );
|
|
||||||
MemWrite( &item->threadWakeup.time, time );
|
|
||||||
MemWrite( &item->threadWakeup.thread, pid );
|
|
||||||
tail.store( magic + 1, std::memory_order_release );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if( memcmp( line, "sched_wakeup", 12 ) == 0 )
|
||||||
|
{
|
||||||
|
line += 14;
|
||||||
|
|
||||||
free( line );
|
while( memcmp( line, "pid", 3 ) != 0 ) line++;
|
||||||
|
line += 4;
|
||||||
|
|
||||||
|
const auto pid = ReadNumber( line );
|
||||||
|
|
||||||
|
Magic magic;
|
||||||
|
auto token = GetToken();
|
||||||
|
auto& tail = token->get_tail_index();
|
||||||
|
auto item = token->enqueue_begin( magic );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::ThreadWakeup );
|
||||||
|
MemWrite( &item->threadWakeup.time, time );
|
||||||
|
MemWrite( &item->threadWakeup.thread, pid );
|
||||||
|
tail.store( magic + 1, std::memory_order_release );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
static void ProcessTraceLines( int fd )
|
||||||
|
{
|
||||||
|
// Linux pipe buffer is 64KB, additional 1KB is for unfinished lines
|
||||||
|
char* buf = (char*)tracy_malloc( (64+1)*1024 );
|
||||||
|
char* line = buf;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
const auto rd = read( fd, line, 64*1024 );
|
||||||
|
if( rd <= 0 ) break;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
if( rd < 64*1024 )
|
||||||
|
{
|
||||||
|
assert( line[rd-1] == '\n' );
|
||||||
|
line = buf;
|
||||||
|
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto end = line + rd;
|
||||||
|
line = end - 1;
|
||||||
|
while( line > buf && *line != '\n' ) line--;
|
||||||
|
if( line > buf )
|
||||||
|
{
|
||||||
|
line++;
|
||||||
|
const auto lsz = end - line;
|
||||||
|
memmove( buf, line, lsz );
|
||||||
|
line = buf + lsz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto end = line + rd;
|
||||||
|
line = buf;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
auto next = line;
|
||||||
|
while( next < end && *next != '\n' ) next++;
|
||||||
|
next++;
|
||||||
|
if( next >= end )
|
||||||
|
{
|
||||||
|
const auto lsz = end - line;
|
||||||
|
memmove( buf, line, lsz );
|
||||||
|
line = buf + lsz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleTraceLine( line );
|
||||||
|
line = next;
|
||||||
|
}
|
||||||
|
if( rd < 64*1024 )
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_free( buf );
|
||||||
|
}
|
||||||
|
|
||||||
void SysTraceWorker( void* ptr )
|
void SysTraceWorker( void* ptr )
|
||||||
{
|
{
|
||||||
SetThreadName( "Tracy SysTrace" );
|
SetThreadName( "Tracy SysTrace" );
|
||||||
@ -619,14 +668,32 @@ void SysTraceWorker( void* ptr )
|
|||||||
{
|
{
|
||||||
// parent
|
// parent
|
||||||
close( pipefd[1] );
|
close( pipefd[1] );
|
||||||
FILE* f = fdopen( pipefd[0], "rb" );
|
ProcessTraceLines( pipefd[0] );
|
||||||
if( !f ) return;
|
close( pipefd[0] );
|
||||||
ProcessTraceLines( f );
|
|
||||||
fclose( f );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
static void ProcessTraceLines( FILE* f )
|
||||||
|
{
|
||||||
|
size_t lsz = 1024;
|
||||||
|
auto line = (char*)malloc( lsz );
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
auto rd = getline( &line, &lsz, f );
|
||||||
|
if( rd < 0 ) break;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() ) continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HandleTraceLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( line );
|
||||||
|
}
|
||||||
|
|
||||||
void SysTraceWorker( void* ptr )
|
void SysTraceWorker( void* ptr )
|
||||||
{
|
{
|
||||||
SetThreadName( "Tracy SysTrace" );
|
SetThreadName( "Tracy SysTrace" );
|
||||||
|
Loading…
Reference in New Issue
Block a user