mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-26 16:04:34 +00:00
Support for setting zone names in lua.
This commit is contained in:
parent
59ec40c045
commit
81735aea2f
@ -96,7 +96,7 @@ Alternatively, you may want to embed the server in your application, the same wh
|
|||||||
|
|
||||||
#### Lua support
|
#### Lua support
|
||||||
|
|
||||||
To profile Lua code using tracy, include the `tracy/TracyLua.hpp` header file in your Lua wrapper and execute `tracy::LuaRegister( lua_State* )` function to add instrumentation support. In your Lua code, add `tracy.ZoneBegin()` and `tracy.ZoneEnd()` calls to mark execution zones. Double check if you have included all return paths! Use `tracy.ZoneText( text )` to set zone text. Use `tracy.Message( text )` to send messages.
|
To profile Lua code using tracy, include the `tracy/TracyLua.hpp` header file in your Lua wrapper and execute `tracy::LuaRegister( lua_State* )` function to add instrumentation support. In your Lua code, add `tracy.ZoneBegin()` and `tracy.ZoneEnd()` calls to mark execution zones. Double check if you have included all return paths! Use `tracy.ZoneText( text )` to set zone text. Use `tracy.ZoneName( name )` to set zone name. Use `tracy.Message( text )` to send messages.
|
||||||
|
|
||||||
Even if tracy is disabled, you still have to pay the no-op function call cost. To prevent that you may want to use the `tracy::LuaRemove( char* script )` function, which will replace instrumentation calls with whitespace. This function does nothing if profiler is enabled.
|
Even if tracy is disabled, you still have to pay the no-op function call cost. To prevent that you may want to use the `tracy::LuaRemove( char* script )` function, which will replace instrumentation calls with whitespace. This function does nothing if profiler is enabled.
|
||||||
|
|
||||||
|
23
TracyLua.hpp
23
TracyLua.hpp
@ -25,6 +25,8 @@ static inline void LuaRegister( lua_State* L )
|
|||||||
lua_pushcfunction( L, detail::noop );
|
lua_pushcfunction( L, detail::noop );
|
||||||
lua_setfield( L, -2, "ZoneText" );
|
lua_setfield( L, -2, "ZoneText" );
|
||||||
lua_pushcfunction( L, detail::noop );
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneName" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
lua_setfield( L, -2, "Message" );
|
lua_setfield( L, -2, "Message" );
|
||||||
lua_setglobal( L, "tracy" );
|
lua_setglobal( L, "tracy" );
|
||||||
}
|
}
|
||||||
@ -173,6 +175,25 @@ static inline int LuaZoneText( lua_State* L )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneName( lua_State* L )
|
||||||
|
{
|
||||||
|
auto txt = lua_tostring( L, 1 );
|
||||||
|
const auto size = strlen( txt );
|
||||||
|
|
||||||
|
Magic magic;
|
||||||
|
auto& token = s_token.ptr;
|
||||||
|
auto ptr = (char*)tracy_malloc( size+1 );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
ptr[size] = '\0';
|
||||||
|
auto& tail = token->get_tail_index();
|
||||||
|
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
|
||||||
|
item->hdr.type = QueueType::ZoneNameLiteral;
|
||||||
|
item->zoneName.thread = GetThreadHandle();
|
||||||
|
item->zoneName.name = (uint64_t)ptr;
|
||||||
|
tail.store( magic + 1, std::memory_order_release );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int LuaMessage( lua_State* L )
|
static inline int LuaMessage( lua_State* L )
|
||||||
{
|
{
|
||||||
auto txt = lua_tostring( L, 1 );
|
auto txt = lua_tostring( L, 1 );
|
||||||
@ -204,6 +225,8 @@ static inline void LuaRegister( lua_State* L )
|
|||||||
lua_setfield( L, -2, "ZoneEnd" );
|
lua_setfield( L, -2, "ZoneEnd" );
|
||||||
lua_pushcfunction( L, detail::LuaZoneText );
|
lua_pushcfunction( L, detail::LuaZoneText );
|
||||||
lua_setfield( L, -2, "ZoneText" );
|
lua_setfield( L, -2, "ZoneText" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneName );
|
||||||
|
lua_setfield( L, -2, "ZoneName" );
|
||||||
lua_pushcfunction( L, detail::LuaMessage );
|
lua_pushcfunction( L, detail::LuaMessage );
|
||||||
lua_setfield( L, -2, "Message" );
|
lua_setfield( L, -2, "Message" );
|
||||||
lua_setglobal( L, "tracy" );
|
lua_setglobal( L, "tracy" );
|
||||||
|
@ -272,6 +272,11 @@ Profiler::DequeueStatus Profiler::Dequeue( moodycamel::ConsumerToken& token )
|
|||||||
SendString( ptr, (const char*)ptr, QueueType::CustomStringData );
|
SendString( ptr, (const char*)ptr, QueueType::CustomStringData );
|
||||||
tracy_free( (void*)ptr );
|
tracy_free( (void*)ptr );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::ZoneNameLiteral:
|
||||||
|
ptr = item->zoneName.name;
|
||||||
|
SendString( ptr, (const char*)ptr, QueueType::CustomStringData );
|
||||||
|
tracy_free( (void*)ptr );
|
||||||
|
break;
|
||||||
case QueueType::Message:
|
case QueueType::Message:
|
||||||
ptr = item->message.text;
|
ptr = item->message.text;
|
||||||
SendString( ptr, (const char*)ptr, QueueType::CustomStringData );
|
SendString( ptr, (const char*)ptr, QueueType::CustomStringData );
|
||||||
|
@ -20,6 +20,7 @@ enum class QueueType : uint8_t
|
|||||||
SourceLocationPayload,
|
SourceLocationPayload,
|
||||||
ZoneText,
|
ZoneText,
|
||||||
ZoneName,
|
ZoneName,
|
||||||
|
ZoneNameLiteral,
|
||||||
LockWait,
|
LockWait,
|
||||||
LockObtain,
|
LockObtain,
|
||||||
LockRelease,
|
LockRelease,
|
||||||
@ -184,6 +185,7 @@ static const size_t QueueDataSize[] = {
|
|||||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload
|
||||||
sizeof( QueueHeader ) + sizeof( QueueZoneText ),
|
sizeof( QueueHeader ) + sizeof( QueueZoneText ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueZoneName ),
|
sizeof( QueueHeader ) + sizeof( QueueZoneName ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneName ), // literal
|
||||||
sizeof( QueueHeader ) + sizeof( QueueLockWait ),
|
sizeof( QueueHeader ) + sizeof( QueueLockWait ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueLockObtain ),
|
sizeof( QueueHeader ) + sizeof( QueueLockObtain ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
||||||
|
@ -14,9 +14,10 @@ struct StringRef
|
|||||||
{
|
{
|
||||||
enum Type { Ptr, Idx };
|
enum Type { Ptr, Idx };
|
||||||
|
|
||||||
StringRef() {}
|
StringRef() : active( 0 ) {}
|
||||||
StringRef( Type t, uint64_t data )
|
StringRef( Type t, uint64_t data )
|
||||||
: isidx( t == Idx )
|
: isidx( t == Idx )
|
||||||
|
, active( 1 )
|
||||||
{
|
{
|
||||||
if( isidx )
|
if( isidx )
|
||||||
{
|
{
|
||||||
@ -33,13 +34,15 @@ struct StringRef
|
|||||||
uint64_t strptr;
|
uint64_t strptr;
|
||||||
uint64_t stridx;
|
uint64_t stridx;
|
||||||
};
|
};
|
||||||
bool isidx;
|
|
||||||
|
uint8_t isidx : 1;
|
||||||
|
uint8_t active : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextData
|
struct TextData
|
||||||
{
|
{
|
||||||
const char* userText;
|
const char* userText;
|
||||||
uint64_t zoneName; // ptr
|
StringRef zoneName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SourceLocation
|
struct SourceLocation
|
||||||
|
@ -564,6 +564,9 @@ void View::Process( const QueueItem& ev )
|
|||||||
case QueueType::ZoneName:
|
case QueueType::ZoneName:
|
||||||
ProcessZoneName( ev.zoneName );
|
ProcessZoneName( ev.zoneName );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::ZoneNameLiteral:
|
||||||
|
ProcessZoneNameLiteral( ev.zoneName );
|
||||||
|
break;
|
||||||
case QueueType::LockWait:
|
case QueueType::LockWait:
|
||||||
ProcessLockWait( ev.lockWait );
|
ProcessLockWait( ev.lockWait );
|
||||||
break;
|
break;
|
||||||
@ -682,7 +685,20 @@ void View::ProcessZoneName( const QueueZoneName& ev )
|
|||||||
auto zone = stack.back();
|
auto zone = stack.back();
|
||||||
CheckString( ev.name );
|
CheckString( ev.name );
|
||||||
std::lock_guard<std::mutex> lock( m_lock );
|
std::lock_guard<std::mutex> lock( m_lock );
|
||||||
GetTextData( *zone )->zoneName = ev.name;
|
GetTextData( *zone )->zoneName = StringRef( StringRef::Ptr, ev.name );
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::ProcessZoneNameLiteral( const QueueZoneName& ev )
|
||||||
|
{
|
||||||
|
auto& stack = m_zoneStack[ev.thread];
|
||||||
|
assert( !stack.empty() );
|
||||||
|
auto zone = stack.back();
|
||||||
|
auto it = m_pendingCustomStrings.find( ev.name );
|
||||||
|
assert( it != m_pendingCustomStrings.end() );
|
||||||
|
m_lock.lock();
|
||||||
|
GetTextData( *zone )->zoneName = StringRef( StringRef::Idx, it->second.idx );
|
||||||
|
m_lock.unlock();
|
||||||
|
m_pendingCustomStrings.erase( it );
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::ProcessLockWait( const QueueLockWait& ev )
|
void View::ProcessLockWait( const QueueLockWait& ev )
|
||||||
@ -2092,7 +2108,7 @@ int View::DrawZoneLevel( const Vector<ZoneEvent*>& vec, bool hover, double pxns,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* zoneName;
|
const char* zoneName;
|
||||||
if( ev.text != -1 && GetTextData( ev )->zoneName )
|
if( ev.text != -1 && GetTextData( ev )->zoneName.active )
|
||||||
{
|
{
|
||||||
zoneName = GetString( GetTextData( ev )->zoneName );
|
zoneName = GetString( GetTextData( ev )->zoneName );
|
||||||
}
|
}
|
||||||
@ -2105,7 +2121,7 @@ int View::DrawZoneLevel( const Vector<ZoneEvent*>& vec, bool hover, double pxns,
|
|||||||
if( ev.text != -1 )
|
if( ev.text != -1 )
|
||||||
{
|
{
|
||||||
auto td = GetTextData( ev );
|
auto td = GetTextData( ev );
|
||||||
if( td->zoneName ) dmul++;
|
if( td->zoneName.active ) dmul++;
|
||||||
if( td->userText ) dmul++;
|
if( td->userText ) dmul++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2858,7 +2874,7 @@ void View::DrawZoneInfoWindow()
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if( ev.text != -1 && GetTextData( ev )->zoneName )
|
if( ev.text != -1 && GetTextData( ev )->zoneName.active )
|
||||||
{
|
{
|
||||||
ImGui::Text( "Zone name: %s", GetString( GetTextData( ev )->zoneName ) );
|
ImGui::Text( "Zone name: %s", GetString( GetTextData( ev )->zoneName ) );
|
||||||
dmul++;
|
dmul++;
|
||||||
@ -2907,7 +2923,7 @@ void View::DrawZoneInfoWindow()
|
|||||||
for( size_t i=0; i<ev.child.size(); i++ )
|
for( size_t i=0; i<ev.child.size(); i++ )
|
||||||
{
|
{
|
||||||
auto& cev = *ev.child[cti[i]];
|
auto& cev = *ev.child[cti[i]];
|
||||||
if( cev.text != -1 && GetTextData( cev )->zoneName )
|
if( cev.text != -1 && GetTextData( cev )->zoneName.active )
|
||||||
{
|
{
|
||||||
ImGui::Text( "%s", GetString( GetTextData( cev )->zoneName ) );
|
ImGui::Text( "%s", GetString( GetTextData( cev )->zoneName ) );
|
||||||
}
|
}
|
||||||
@ -3070,7 +3086,7 @@ void View::ZoneTooltip( const ZoneEvent& ev )
|
|||||||
if( ev.text != -1 )
|
if( ev.text != -1 )
|
||||||
{
|
{
|
||||||
auto td = GetTextData( ev );
|
auto td = GetTextData( ev );
|
||||||
if( td->zoneName ) dmul++;
|
if( td->zoneName.active ) dmul++;
|
||||||
if( td->userText ) dmul++;
|
if( td->userText ) dmul++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3081,7 +3097,7 @@ void View::ZoneTooltip( const ZoneEvent& ev )
|
|||||||
|
|
||||||
const char* func;
|
const char* func;
|
||||||
const char* zoneName;
|
const char* zoneName;
|
||||||
if( ev.text != -1 && GetTextData( ev )->zoneName )
|
if( ev.text != -1 && GetTextData( ev )->zoneName.active )
|
||||||
{
|
{
|
||||||
zoneName = GetString( GetTextData( ev )->zoneName );
|
zoneName = GetString( GetTextData( ev )->zoneName );
|
||||||
func = GetString( srcloc.function );
|
func = GetString( srcloc.function );
|
||||||
@ -3144,7 +3160,6 @@ TextData* View::GetTextData( ZoneEvent& zone )
|
|||||||
{
|
{
|
||||||
auto td = m_slab.Alloc<TextData>();
|
auto td = m_slab.Alloc<TextData>();
|
||||||
td->userText = nullptr;
|
td->userText = nullptr;
|
||||||
td->zoneName = 0;
|
|
||||||
zone.text = m_textData.size();
|
zone.text = m_textData.size();
|
||||||
m_textData.push_back( td );
|
m_textData.push_back( td );
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ private:
|
|||||||
void ProcessFrameMark( const QueueFrameMark& ev );
|
void ProcessFrameMark( const QueueFrameMark& ev );
|
||||||
void ProcessZoneText( const QueueZoneText& ev );
|
void ProcessZoneText( const QueueZoneText& ev );
|
||||||
void ProcessZoneName( const QueueZoneName& ev );
|
void ProcessZoneName( const QueueZoneName& ev );
|
||||||
|
void ProcessZoneNameLiteral( const QueueZoneName& ev );
|
||||||
void ProcessLockWait( const QueueLockWait& ev );
|
void ProcessLockWait( const QueueLockWait& ev );
|
||||||
void ProcessLockObtain( const QueueLockObtain& ev );
|
void ProcessLockObtain( const QueueLockObtain& ev );
|
||||||
void ProcessLockRelease( const QueueLockRelease& ev );
|
void ProcessLockRelease( const QueueLockRelease& ev );
|
||||||
|
Loading…
Reference in New Issue
Block a user