2025-07-05 13:28:41 +03:30
|
|
|
#include <engine/debug/instrumentor.hpp>
|
2021-07-12 15:20:47 +04:30
|
|
|
|
|
|
|
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
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
return make_scope<Instrumentor>(new Instrumentor);
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
Instrumentor::Instrumentor(): m_current_session_count(0u)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// #todo: maintenance
|
2025-07-05 15:36:53 +03:30
|
|
|
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
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +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));
|
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
m_output_file_stream.open(outputPath);
|
|
|
|
m_output_file_stream << "{\"traceEvents\":[";
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Instrumentor::end_session_impl()
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
if (m_current_session_count == 0u)
|
2025-07-05 15:36:53 +03:30
|
|
|
lt_log(warn, "0 profiling for the ended session");
|
2022-03-07 21:57:00 +03:30
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
m_current_session_count = 0u;
|
2022-03-07 21:57:00 +03:30
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
m_output_file_stream << "]}";
|
|
|
|
m_output_file_stream.flush();
|
|
|
|
m_output_file_stream.close();
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Instrumentor::submit_scope_profile_impl(const ScopeProfileResult &profileResult)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
if (m_current_session_count++ == 0u)
|
|
|
|
m_output_file_stream << "{";
|
2022-03-07 21:57:00 +03:30
|
|
|
else
|
2025-07-05 14:23:01 +03:30
|
|
|
m_output_file_stream << ",{";
|
|
|
|
|
|
|
|
m_output_file_stream << "\"name\":\"" << profileResult.name << "\",";
|
|
|
|
m_output_file_stream << "\"cat\": \"scope\",";
|
|
|
|
m_output_file_stream << "\"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-05 14:23:01 +03:30
|
|
|
: m_result({ scopeName, 0, 0, 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();
|
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
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
|
|
|
|
2025-07-05 14:23:01 +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()
|
2025-07-05 14:23:01 +03:30
|
|
|
- m_result.start;
|
2022-03-07 21:57:00 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
Instrumentor::submit_scope_profile(m_result);
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Light
|