mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 16:40:18 +00:00
Only built when -DBUILD_PROFILED is defined. To enable profiling set output file name using the UG_PROFILE enviroment variable. The profiler will then output a file which contains profiling data viewable in Chromium (chrome://tracing). Use the macro PROFILE_FUNC at the start of c++ functions you want to include in the profiling
144 lines
3.5 KiB
C++
144 lines
3.5 KiB
C++
#ifndef PROFILE_TIMER_HPP
|
|
#define PROFILE_TIMER_HPP
|
|
|
|
#ifdef BUILD_PROFILED
|
|
|
|
#define C_PROFILER_PUSH(name) \
|
|
push_prof_timer((name))
|
|
|
|
#define C_PROFILER_POP \
|
|
pop_prof_timer()
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#include <chrono>
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <fstream>
|
|
#include <functional>
|
|
|
|
#define THREAD_EVENT_BUF_SIZE 256
|
|
|
|
#define PROFILE_FUNC \
|
|
Profile_timer PROFILER_PROFILE_TIMER_FUNC(Profiler_thread_inst::get_instance(), __PRETTY_FUNCTION__); \
|
|
Profile_timer PROFILER_PROFILE_TIMER_DETAIL(Profiler_thread_inst::get_instance(), "");
|
|
|
|
#define PROFILE_DETAIL(name) \
|
|
PROFILER_PROFILE_TIMER_DETAIL = Profile_timer(Profiler_thread_inst::get_instance(), (name));
|
|
|
|
|
|
struct Profile_event {
|
|
Profile_event(std::string name,
|
|
std::thread::id thread_id) :
|
|
name(name),
|
|
start(),
|
|
end(),
|
|
thread_id(thread_id) { }
|
|
|
|
std::string name;
|
|
std::chrono::steady_clock::time_point::rep start;
|
|
std::chrono::steady_clock::time_point::rep end;
|
|
std::thread::id thread_id;
|
|
};
|
|
|
|
class Profiler_thread_inst;
|
|
|
|
class Profiler {
|
|
friend Profiler_thread_inst;
|
|
public:
|
|
static Profiler& get_instance();
|
|
|
|
Profiler(const Profiler&) = delete;
|
|
Profiler(Profiler&&) = delete;
|
|
Profiler& operator=(Profiler&&) = delete;
|
|
Profiler& operator=(const Profiler&) = delete;
|
|
|
|
void write_events(const std::vector<Profile_event>& events);
|
|
|
|
static std::chrono::steady_clock::time_point get_start_point(){
|
|
return start_point;
|
|
}
|
|
|
|
private:
|
|
Profiler();
|
|
|
|
std::mutex io_mut;
|
|
std::ofstream out_file;
|
|
std::thread::id pid;
|
|
|
|
bool active = false;
|
|
|
|
static std::chrono::steady_clock::time_point start_point;
|
|
};
|
|
|
|
class Profile_timer;
|
|
|
|
class Profiler_thread_inst {
|
|
friend Profile_timer;
|
|
public:
|
|
|
|
Profiler_thread_inst(Profiler& profiler);
|
|
~Profiler_thread_inst();
|
|
|
|
Profiler_thread_inst(const Profiler_thread_inst&) = delete;
|
|
Profiler_thread_inst(Profiler_thread_inst&&) = delete;
|
|
Profiler_thread_inst& operator=(Profiler_thread_inst&&) = delete;
|
|
Profiler_thread_inst& operator=(const Profiler_thread_inst&) = delete;
|
|
|
|
static Profiler_thread_inst& get_instance();
|
|
|
|
void add_event(Profile_event&& event);
|
|
|
|
void push_timer(const char *name);
|
|
void pop_timer();
|
|
|
|
private:
|
|
Profiler& profiler;
|
|
std::vector<Profile_event> thread_events;
|
|
std::chrono::steady_clock::time_point::rep last_ts;
|
|
std::vector<Profile_timer> c_timers;
|
|
};
|
|
|
|
class Profile_timer {
|
|
friend Profiler;
|
|
public:
|
|
Profile_timer(Profiler_thread_inst& profiler, std::string name);
|
|
Profile_timer(Profile_timer&&);
|
|
Profile_timer(const Profile_timer&) = delete;
|
|
~Profile_timer();
|
|
|
|
Profile_timer& operator=(Profile_timer&& rhs);
|
|
Profile_timer& operator=(const Profile_timer&) = delete;
|
|
|
|
private:
|
|
void commit();
|
|
|
|
std::reference_wrapper<Profiler_thread_inst> profiler;
|
|
Profile_event event;
|
|
};
|
|
|
|
#endif //__cplusplus
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif //__cplusplus
|
|
|
|
void push_prof_timer(const char *name);
|
|
void pop_prof_timer();
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif //__cplusplus
|
|
|
|
#else //BUILD_PROFILED
|
|
|
|
#define PROFILE_FUNC
|
|
#define PROFILE_DETAIL(name)
|
|
#define C_PROFILER_PUSH(name)
|
|
#define C_PROFILER_POP
|
|
|
|
#endif //BUILD_PROFILED
|
|
|
|
#endif
|