mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +00:00
u/metrics: Add functions to write a metrics file
This commit is contained in:
parent
57a31fde7c
commit
7fa20a8b46
|
@ -61,6 +61,8 @@ add_library(
|
|||
u_json.hpp
|
||||
u_logging.c
|
||||
u_logging.h
|
||||
u_metrics.c
|
||||
u_metrics.h
|
||||
u_misc.c
|
||||
u_misc.h
|
||||
u_pacing.h
|
||||
|
@ -98,7 +100,15 @@ add_library(
|
|||
u_worker.hpp
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/u_git_tag.c"
|
||||
)
|
||||
target_link_libraries(aux_util PUBLIC aux-includes aux_generated_bindings aux_os aux_math)
|
||||
target_link_libraries(
|
||||
aux_util
|
||||
PUBLIC
|
||||
xrt-external-nanopb
|
||||
aux-includes
|
||||
aux_generated_bindings
|
||||
aux_os
|
||||
aux_math
|
||||
)
|
||||
|
||||
# Is basically used everywhere, unavoidable.
|
||||
if(XRT_HAVE_SYSTEM_CJSON)
|
||||
|
|
230
src/xrt/auxiliary/util/u_metrics.c
Normal file
230
src/xrt/auxiliary/util/u_metrics.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
// Copyright 2022, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Metrics saving functions.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
|
||||
#include "os/os_threading.h"
|
||||
|
||||
#include "util/u_metrics.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
#include "monado_metrics.pb.h"
|
||||
#include "pb_encode.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 1
|
||||
|
||||
static FILE *g_file = NULL;
|
||||
static struct os_mutex g_file_mutex;
|
||||
static bool g_metrics_initialized = false;
|
||||
|
||||
DEBUG_GET_ONCE_OPTION(metrics_file, "XRT_METRICS_FILE", NULL)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Helper functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
write_record(monado_metrics_Record *r)
|
||||
{
|
||||
uint8_t buffer[monado_metrics_Record_size + 10]; // Including submessage
|
||||
|
||||
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
||||
bool ret = pb_encode_submessage(&stream, &monado_metrics_Record_msg, r);
|
||||
if (!ret) {
|
||||
U_LOG_E("Failed to encode metrics message!");
|
||||
return;
|
||||
}
|
||||
|
||||
os_mutex_lock(&g_file_mutex);
|
||||
|
||||
fwrite(buffer, stream.bytes_written, 1, g_file);
|
||||
|
||||
os_mutex_unlock(&g_file_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
write_version(uint32_t major, uint32_t minor)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_version_tag;
|
||||
record.record.version.major = major;
|
||||
record.record.version.minor = minor;
|
||||
|
||||
write_record(&record);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
u_metrics_init()
|
||||
{
|
||||
const char *str = debug_get_option_metrics_file();
|
||||
if (str == NULL) {
|
||||
U_LOG_D("No metrics file!");
|
||||
return;
|
||||
}
|
||||
|
||||
g_file = fopen(str, "wb");
|
||||
if (g_file == NULL) {
|
||||
U_LOG_E("Could not open '%s'!", str);
|
||||
return;
|
||||
}
|
||||
|
||||
os_mutex_init(&g_file_mutex);
|
||||
|
||||
g_metrics_initialized = true;
|
||||
|
||||
write_version(VERSION_MAJOR, VERSION_MINOR);
|
||||
|
||||
U_LOG_I("Opened metrics file: '%s'", str);
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_close()
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
U_LOG_I("Closing metrics file: '%s'", debug_get_option_metrics_file());
|
||||
|
||||
// At least try to avoid races.
|
||||
os_mutex_lock(&g_file_mutex);
|
||||
fflush(g_file);
|
||||
fclose(g_file);
|
||||
g_file = NULL;
|
||||
os_mutex_unlock(&g_file_mutex);
|
||||
|
||||
os_mutex_destroy(&g_file_mutex);
|
||||
|
||||
g_metrics_initialized = false;
|
||||
}
|
||||
|
||||
bool
|
||||
u_metrics_is_active(void)
|
||||
{
|
||||
return g_metrics_initialized;
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_write_session_frame(struct u_metrics_session_frame *umsf)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_session_frame_tag;
|
||||
|
||||
#define COPY(_0, _1, _2, _3, FIELD, _4) (record.record.session_frame.FIELD = umsf->FIELD);
|
||||
monado_metrics_SessionFrame_FIELDLIST(COPY, 0);
|
||||
#undef COPY
|
||||
|
||||
|
||||
write_record(&record);
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_write_used(struct u_metrics_used *umu)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_used_tag;
|
||||
|
||||
#define COPY(_0, _1, _2, _3, FIELD, _4) (record.record.used.FIELD = umu->FIELD);
|
||||
monado_metrics_Used_FIELDLIST(COPY, 0);
|
||||
#undef COPY
|
||||
|
||||
|
||||
write_record(&record);
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_write_system_frame(struct u_metrics_system_frame *umsf)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_system_frame_tag;
|
||||
|
||||
#define COPY(_0, _1, _2, _3, FIELD, _4) (record.record.system_frame.FIELD = umsf->FIELD);
|
||||
monado_metrics_SystemFrame_FIELDLIST(COPY, 0);
|
||||
#undef COPY
|
||||
|
||||
|
||||
write_record(&record);
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_write_system_gpu_info(struct u_metrics_system_gpu_info *umgi)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_system_gpu_info_tag;
|
||||
|
||||
#define COPY(_0, _1, _2, _3, FIELD, _4) (record.record.system_gpu_info.FIELD = umgi->FIELD);
|
||||
monado_metrics_SystemGpuInfo_FIELDLIST(COPY, 0);
|
||||
#undef COPY
|
||||
|
||||
|
||||
write_record(&record);
|
||||
}
|
||||
|
||||
void
|
||||
u_metrics_write_system_present_info(struct u_metrics_system_present_info *umpi)
|
||||
{
|
||||
if (!g_metrics_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
monado_metrics_Record record = monado_metrics_Record_init_default;
|
||||
|
||||
// Select which filed is used.
|
||||
record.which_record = monado_metrics_Record_system_present_info_tag;
|
||||
|
||||
#define COPY(_0, _1, _2, _3, FIELD, _4) (record.record.system_present_info.FIELD = umpi->FIELD);
|
||||
monado_metrics_SystemPresentInfo_FIELDLIST(COPY, 0);
|
||||
#undef COPY
|
||||
|
||||
|
||||
write_record(&record);
|
||||
}
|
110
src/xrt/auxiliary/util/u_metrics.h
Normal file
110
src/xrt/auxiliary/util/u_metrics.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Copyright 2022, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Metrics saving functions.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xrt/xrt_compiler.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct u_metrics_session_frame
|
||||
{
|
||||
int64_t session_id;
|
||||
int64_t frame_id;
|
||||
uint64_t predicted_frame_time_ns;
|
||||
uint64_t predicted_wake_up_time_ns;
|
||||
uint64_t predicted_gpu_done_time_ns;
|
||||
uint64_t predicted_display_time_ns;
|
||||
uint64_t predicted_display_period_ns;
|
||||
uint64_t display_time_ns;
|
||||
uint64_t when_predicted_ns;
|
||||
uint64_t when_wait_woke_ns;
|
||||
uint64_t when_begin_ns;
|
||||
uint64_t when_delivered_ns;
|
||||
uint64_t when_gpu_done_ns;
|
||||
bool discarded;
|
||||
};
|
||||
|
||||
struct u_metrics_used
|
||||
{
|
||||
int64_t session_id;
|
||||
int64_t session_frame_id;
|
||||
int64_t system_frame_id;
|
||||
uint64_t when_ns;
|
||||
};
|
||||
|
||||
struct u_metrics_system_frame
|
||||
{
|
||||
int64_t frame_id;
|
||||
uint64_t predicted_display_time_ns;
|
||||
uint64_t predicted_display_period_ns;
|
||||
uint64_t desired_present_time_ns;
|
||||
uint64_t wake_up_time_ns;
|
||||
uint64_t present_slop_ns;
|
||||
};
|
||||
|
||||
struct u_metrics_system_gpu_info
|
||||
{
|
||||
int64_t frame_id;
|
||||
uint64_t gpu_start_ns;
|
||||
uint64_t gpu_end_ns;
|
||||
uint64_t when_ns;
|
||||
};
|
||||
|
||||
struct u_metrics_system_present_info
|
||||
{
|
||||
int64_t frame_id;
|
||||
uint64_t expected_comp_time_ns;
|
||||
uint64_t predicted_wake_up_time_ns;
|
||||
uint64_t predicted_done_time_ns;
|
||||
uint64_t predicted_display_time_ns;
|
||||
uint64_t when_predict_ns;
|
||||
uint64_t when_woke_ns;
|
||||
uint64_t when_began_ns;
|
||||
uint64_t when_submitted_ns;
|
||||
uint64_t when_infoed_ns;
|
||||
uint64_t desired_present_time_ns;
|
||||
uint64_t present_slop_ns;
|
||||
uint64_t present_margin_ns;
|
||||
uint64_t actual_present_time_ns;
|
||||
uint64_t earliest_present_time_ns;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
u_metrics_init(void);
|
||||
|
||||
void
|
||||
u_metrics_close(void);
|
||||
|
||||
bool
|
||||
u_metrics_is_active(void);
|
||||
|
||||
void
|
||||
u_metrics_write_session_frame(struct u_metrics_session_frame *umsf);
|
||||
|
||||
void
|
||||
u_metrics_write_used(struct u_metrics_used *umu);
|
||||
|
||||
void
|
||||
u_metrics_write_system_frame(struct u_metrics_system_frame *umsf);
|
||||
|
||||
void
|
||||
u_metrics_write_system_gpu_info(struct u_metrics_system_gpu_info *umgi);
|
||||
|
||||
void
|
||||
u_metrics_write_system_present_info(struct u_metrics_system_present_info *umpi);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in a new issue