light/modules/engine/src/debug/instrumentor.cpp

84 lines
2.2 KiB
C++
Raw Normal View History

2025-07-05 13:28:41 +03:30
#include <engine/debug/instrumentor.hpp>
namespace Light {
2025-07-05 16:07:51 +03:30
Instrumentor *Instrumentor::s_context = nullptr;
2022-03-07 21:57:00 +03:30
2025-07-06 14:02:50 +03:30
auto Instrumentor::create() -> Scope<Instrumentor>
2022-03-07 21:57:00 +03:30
{
return make_scope<Instrumentor>(new Instrumentor);
2022-03-07 21:57:00 +03:30
}
2025-07-06 16:52:50 +03:30
Instrumentor::Instrumentor()
2022-03-07 21:57:00 +03:30
{
// #todo: maintenance
lt_assert(
2025-07-05 16:07:51 +03:30
!s_context,
2025-07-05 13:28:41 +03:30
"An instance of 'Instrumentor' already exists, do not construct this class!"
);
2025-07-05 16:07:51 +03:30
s_context = this;
2022-03-07 21:57:00 +03:30
}
void Instrumentor::begin_session_impl(const std::string &outputPath)
2022-03-07 21:57:00 +03:30
{
std::filesystem::create_directory(outputPath.substr(0, outputPath.find_last_of('/') + 1));
m_output_file_stream.open(outputPath);
m_output_file_stream << "{\"traceEvents\":[";
2022-03-07 21:57:00 +03:30
}
void Instrumentor::end_session_impl()
2022-03-07 21:57:00 +03:30
{
2025-07-06 16:52:50 +03:30
if (m_current_session_count == 0u) {
2025-07-06 16:30:38 +03:30
log_wrn("0 profiling for the ended session");
2025-07-06 16:52:50 +03:30
}
2022-03-07 21:57:00 +03:30
m_current_session_count = 0u;
2022-03-07 21:57:00 +03:30
m_output_file_stream << "]}";
m_output_file_stream.flush();
m_output_file_stream.close();
2022-03-07 21:57:00 +03:30
}
void Instrumentor::submit_scope_profile_impl(const ScopeProfileResult &profileResult)
2022-03-07 21:57:00 +03:30
{
2025-07-06 16:52:50 +03:30
if (m_current_session_count++ == 0u) {
m_output_file_stream << "{";
2025-07-06 16:52:50 +03:30
} else {
m_output_file_stream << ",{";
2025-07-06 16:52:50 +03:30
}
2025-07-06 16:52:50 +03:30
m_output_file_stream << R"("name":")" << profileResult.name << "\",";
m_output_file_stream << R"("cat": "scope",)";
m_output_file_stream << R"("ph": "X",)";
m_output_file_stream << "\"ts\":" << profileResult.start << ",";
m_output_file_stream << "\"dur\":" << profileResult.duration << ",";
m_output_file_stream << "\"pid\":0,";
m_output_file_stream << "\"tid\":" << profileResult.threadID << "";
m_output_file_stream << "}";
2022-03-07 21:57:00 +03:30
}
2025-07-05 13:28:41 +03:30
InstrumentorTimer::InstrumentorTimer(const std::string &scopeName)
2025-07-06 16:52:50 +03:30
: m_result({ .name=scopeName, .start=0, .duration=0, .threadID=0 })
, m_start(std::chrono::steady_clock::now())
2022-03-07 21:57:00 +03:30
{
}
InstrumentorTimer::~InstrumentorTimer()
{
auto end = std::chrono::steady_clock::now();
m_result.start = std::chrono::time_point_cast<std::chrono::microseconds>(m_start)
2025-07-05 13:28:41 +03:30
.time_since_epoch()
.count();
2025-07-06 14:02:50 +03:30
m_result.duration = std::chrono::time_point_cast<std::chrono::microseconds>(end)
2025-07-05 13:28:41 +03:30
.time_since_epoch()
.count()
- m_result.start;
2022-03-07 21:57:00 +03:30
Instrumentor::submit_scope_profile(m_result);
2022-03-07 21:57:00 +03:30
}
} // namespace Light