Reduce template code

This commit is contained in:
Joshua Kriegshauser 2024-09-24 15:10:42 -07:00
parent 201dcb6a8a
commit cc860fe56a
2 changed files with 73 additions and 61 deletions

View File

@ -3095,6 +3095,69 @@ bool Profiler::CommitData()
return ret;
}
char* Profiler::SafeCopyProlog( const char* data, size_t size )
{
bool success = true;
char* buf = m_safeSendBuffer;
#ifndef NDEBUG
assert( !m_inUse.exchange(true) );
#endif
if( size > m_safeSendBufferSize )
{
buf = (char*)tracy_malloc( size );
}
#ifdef _WIN32
__try
{
memcpy( buf, data, size );
}
__except( 1 /*EXCEPTION_EXECUTE_HANDLER*/ )
{
success = false;
}
#else
// Send through the pipe to ensure safe reads
for( size_t offset = 0; offset != size; /*in loop*/ )
{
size_t sendsize = size - offset;
ssize_t result1, result2;
while( ( result1 = write( m_pipe[1], data + offset, sendsize ) ) < 0 && errno == EINTR )
/* retry */;
if( result1 < 0 )
{
success = false;
break;
}
while( ( result2 = read( m_pipe[0], buf + offset, result1 ) ) < 0 && errno == EINTR )
/* retry */;
if( result2 != result1 )
{
success = false;
break;
}
offset += result1;
}
#endif
if( success )
return buf;
SafeCopyEpilog( buf );
return nullptr;
}
void Profiler::SafeCopyEpilog( char* buf )
{
if( buf != m_safeSendBuffer )
tracy_free( buf );
#ifndef NDEBUG
m_inUse.store( false );
#endif
}
bool Profiler::SendData( const char* data, size_t len )
{
const lz4sz_t lz4sz = LZ4_compress_fast_continue( (LZ4_stream_t*)m_stream, data, m_lz4Buf + sizeof( lz4sz_t ), (int)len, LZ4Size, 1 );
@ -4050,7 +4113,7 @@ void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size )
else
{
// 'symbol' may have come from a module that has since unloaded, perform a safe copy before sending
if( withSafeCopy( (const char*)symbol, size, [this, symbol]( const char* buf, size_t size ) {
if( WithSafeCopy( (const char*)symbol, size, [this, symbol]( const char* buf, size_t size ) {
SendLongString( symbol, buf, size, QueueType::SymbolCode );
}))
return;

View File

@ -833,70 +833,19 @@ private:
m_bufferOffset += int( len );
}
template<class Callable> // must be void(const char* buf, size_t size)
bool withSafeCopy(const char* p, size_t size, Callable&& callable)
char* SafeCopyProlog( const char* p, size_t size );
void SafeCopyEpilog( char* buf );
template<class Callable> // must be void( const char* buf, size_t size )
bool WithSafeCopy( const char* p, size_t size, Callable&& callable )
{
bool success = true, heap = false;
char* buf = m_safeSendBuffer;
#ifndef NDEBUG
assert( !m_inUse.exchange(true) );
#endif
if( size > m_safeSendBufferSize )
{
heap = true;
buf = (char*)tracy_malloc( size );
}
#ifdef _WIN32
__try
{
memcpy( buf, p, size );
}
__except( 1 /*EXCEPTION_EXECUTE_HANDLER*/ )
{
success = false;
}
#else
// Send through the pipe to ensure safe reads
for( size_t offset = 0; offset != size; /*in loop*/ )
{
size_t sendsize = size - offset;
ssize_t result1, result2;
while( ( result1 = write( m_pipe[1], p + offset, sendsize ) ) < 0 && errno == EINTR )
/* retry */;
if( result1 < 0 )
{
success = false;
break;
}
while( ( result2 = read( m_pipe[0], buf + offset, result1 ) ) < 0 && errno == EINTR )
/* retry */;
if( result2 != result1 )
{
success = false;
break;
}
offset += result1;
}
#endif
if( success )
if( char* buf = SafeCopyProlog( p, size ) )
{
callable( buf, size );
SafeCopyEpilog( buf );
return true;
}
if( heap )
{
tracy_free( buf );
}
#ifndef NDEBUG
m_inUse.store( false );
#endif
return success;
return false;
}
bool SendData( const char* data, size_t len );