tracy/client/TracyProfiler.hpp

116 lines
2.6 KiB
C++
Raw Normal View History

2017-09-10 15:43:56 +00:00
#ifndef __TRACYPROFILER_HPP__
#define __TRACYPROFILER_HPP__
#include <atomic>
#include <chrono>
2017-09-10 18:08:42 +00:00
#include <stdint.h>
2017-09-10 15:43:56 +00:00
#include <thread>
#include "concurrentqueue.h"
#include "../common/tracy_lz4.hpp"
2017-09-13 20:56:08 +00:00
#include "../common/TracyQueue.hpp"
2017-09-10 18:09:14 +00:00
#if defined _MSC_VER || defined __CYGWIN__
# include <intrin.h>
#endif
2017-10-03 13:35:43 +00:00
#if defined _MSC_VER || defined __CYGWIN__ || defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64
# define TRACY_RDTSCP_SUPPORTED
#endif
2017-09-10 15:43:56 +00:00
namespace tracy
{
class Socket;
struct SourceLocation
{
const char* function;
const char* file;
uint32_t line;
uint32_t color;
};
extern moodycamel::ConcurrentQueue<QueueItem> s_queue;
2017-10-03 13:16:48 +00:00
extern thread_local moodycamel::ProducerToken s_token;
2017-10-03 12:50:55 +00:00
using Magic = moodycamel::ConcurrentQueueDefaultTraits::index_t;
2017-09-10 15:43:56 +00:00
class Profiler
{
public:
Profiler();
~Profiler();
2017-10-03 13:35:43 +00:00
#ifdef TRACY_RDTSCP_SUPPORTED
static tracy_force_inline int64_t tracy_rdtscp( int8_t& cpu )
{
#if defined _MSC_VER || defined __CYGWIN__
unsigned int ui;
2017-10-01 17:11:01 +00:00
const auto t = int64_t( __rdtscp( &ui ) );
cpu = (int8_t)ui;
return t;
2017-10-03 13:27:07 +00:00
#elif defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64
uint64_t eax, edx;
unsigned int ui;
asm volatile ( "rdtscp" : "=a" (eax), "=d" (edx), "=c" (ui) :: );
cpu = (int8_t)ui;
return ( edx << 32 ) + eax;
2017-10-03 13:35:43 +00:00
#endif
}
#endif
static tracy_force_inline int64_t GetTime( int8_t& cpu )
{
#ifdef TRACY_RDTSCP_SUPPORTED
return tracy_rdtscp( cpu );
#else
2017-10-01 17:11:01 +00:00
cpu = -1;
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
#endif
}
2017-09-10 18:08:42 +00:00
2017-10-03 13:10:25 +00:00
static tracy_force_inline void FrameMark()
{
int8_t cpu;
2017-10-03 12:50:55 +00:00
Magic magic;
auto& token = s_token;
auto item = s_queue.enqueue_begin( token, magic );
item->hdr.type = QueueType::FrameMarkMsg;
2017-10-03 14:41:32 +00:00
item->frameMark.time = GetTime( cpu );
s_queue.enqueue_finish( token, magic );
}
2017-09-10 18:09:14 +00:00
static bool ShouldExit();
2017-09-10 15:43:56 +00:00
private:
void Worker();
bool SendData( const char* data, size_t len );
bool SendString( uint64_t ptr, const char* str, QueueType type );
void SendSourceLocation( uint64_t ptr );
bool HandleServerQuery();
2017-09-23 19:33:05 +00:00
void CalibrateTimer();
2017-09-24 14:02:09 +00:00
void CalibrateDelay();
2017-09-23 19:33:05 +00:00
double m_timerMul;
2017-09-29 16:29:39 +00:00
uint64_t m_resolution;
2017-09-24 14:02:09 +00:00
uint64_t m_delay;
2017-09-10 18:14:16 +00:00
int64_t m_timeBegin;
2017-09-22 23:37:07 +00:00
uint64_t m_mainThread;
uint64_t m_epoch;
2017-09-10 15:43:56 +00:00
std::thread m_thread;
std::atomic<bool> m_shutdown;
std::unique_ptr<Socket> m_sock;
LZ4_stream_t* m_stream;
char* m_buffer;
int m_bufferOffset;
2017-09-10 15:43:56 +00:00
};
};
#endif