diff --git a/TracyClient.cpp b/TracyClient.cpp index 7a2cd288..e5f8b370 100644 --- a/TracyClient.cpp +++ b/TracyClient.cpp @@ -18,6 +18,7 @@ #include "common/tracy_lz4.cpp" #include "client/TracyProfiler.cpp" #include "client/TracyCallstack.cpp" +#include "client/TracySysTime.cpp" #include "common/TracySocket.cpp" #include "client/tracy_rpmalloc.cpp" diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index ce7cfcef..fd87aa2a 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -1147,6 +1147,7 @@ void Profiler::Worker() int keepAlive = 0; for(;;) { + ProcessSysTime(); const auto status = Dequeue( token ); const auto serialStatus = DequeueSerial(); if( status == ConnectionLost || serialStatus == ConnectionLost ) @@ -1859,6 +1860,26 @@ void Profiler::SendCallstack( int depth, uint64_t thread, const char* skipBefore #endif } +#ifdef TRACY_HAS_SYSTIME +void Profiler::ProcessSysTime() +{ + auto t = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + if( t - m_sysTimeLast > 100000000 ) // 100 ms + { + m_sysTimeLast = t; + + Magic magic; + auto token = GetToken(); + auto& tail = token->get_tail_index(); + auto item = token->enqueue_begin( magic ); + MemWrite( &item->hdr.type, QueueType::SysTimeReport ); + MemWrite( &item->sysTime.time, GetTime() ); + MemWrite( &item->sysTime.sysTime, m_sysTime.Get() ); + tail.store( magic + 1, std::memory_order_release ); + } +} +#endif + } #ifdef __cplusplus diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index 67999272..51135134 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -9,6 +9,7 @@ #include "concurrentqueue.h" #include "TracyCallstack.hpp" +#include "TracySysTime.hpp" #include "TracyFastVector.hpp" #include "../common/tracy_lz4.hpp" #include "../common/TracyQueue.hpp" @@ -467,6 +468,15 @@ private: TracyMutex m_deferredLock; FastVector m_deferredQueue; #endif + +#ifdef TRACY_HAS_SYSTIME + void ProcessSysTime(); + + SysTime m_sysTime; + uint64_t m_sysTimeLast = 0; +#else + void ProcessSysTime() {} +#endif }; }; diff --git a/client/TracySysTime.cpp b/client/TracySysTime.cpp new file mode 100644 index 00000000..48f3ac27 --- /dev/null +++ b/client/TracySysTime.cpp @@ -0,0 +1,59 @@ +#include "TracySysTime.hpp" + +#ifdef TRACY_HAS_SYSTIME + +# ifdef _WIN32 +# include +# endif + +namespace tracy +{ + +# ifdef _WIN32 + +static inline uint64_t ConvertTime( const FILETIME& t ) +{ + return ( uint64_t( t.dwHighDateTime ) << 32 ) | uint64_t( t.dwLowDateTime ); +} + +SysTime::SysTime() +{ + FILETIME idleTime; + FILETIME kernelTime; + FILETIME userTime; + + GetSystemTimes( &idleTime, &kernelTime, &userTime ); + + idle = ConvertTime( idleTime ); + const auto kernel = ConvertTime( kernelTime ); + const auto user = ConvertTime( userTime ); + used = kernel + user; +} + +float SysTime::Get() +{ + FILETIME idleTime; + FILETIME kernelTime; + FILETIME userTime; + + GetSystemTimes( &idleTime, &kernelTime, &userTime ); + + const auto newIdle = ConvertTime( idleTime ); + const auto kernel = ConvertTime( kernelTime ); + const auto user = ConvertTime( userTime ); + const auto newUsed = kernel + user; + + const auto diffIdle = newIdle - idle; + const auto diffUsed = newUsed - used; + + idle = newIdle; + used = newUsed; + + return diffUsed == 0 ? 0 : ( diffUsed - diffIdle ) * 100.f / diffUsed; +} + +# endif + +} + +#endif diff --git a/client/TracySysTime.hpp b/client/TracySysTime.hpp new file mode 100644 index 00000000..298ec5f6 --- /dev/null +++ b/client/TracySysTime.hpp @@ -0,0 +1,30 @@ +#ifndef __TRACYSYSTIME_HPP__ +#define __TRACYSYSTIME_HPP__ + +#ifdef _WIN32 +# define TRACY_HAS_SYSTIME +#endif + +#ifdef TRACY_HAS_SYSTIME + +#include + +namespace tracy +{ + +class SysTime +{ +public: + SysTime(); + float Get(); + +private: +# ifdef _WIN32 + uint64_t idle, used; +# endif +}; + +} +#endif + +#endif diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 848103d9..7246ffb2 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -48,6 +48,7 @@ enum class QueueType : uint8_t MemFreeCallstack, CallstackFrameSize, CallstackFrame, + SysTimeReport, StringData, ThreadName, CustomStringData, @@ -265,6 +266,12 @@ struct QueueCrashReport uint64_t text; // ptr }; +struct QueueSysTime +{ + int64_t time; + float sysTime; +}; + struct QueueHeader { union @@ -305,6 +312,7 @@ struct QueueItem QueueCallstackFrameSize callstackFrameSize; QueueCallstackFrame callstackFrame; QueueCrashReport crashReport; + QueueSysTime sysTime; }; }; @@ -354,6 +362,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ), sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ), + sizeof( QueueHeader ) + sizeof( QueueSysTime ), // keep all QueueStringTransfer below sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name