diff --git a/CMakeLists.txt b/CMakeLists.txt index 85c7598a6..be2f8ab62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,6 +116,7 @@ endif() option(BUILD_TESTING "Enable building of the test suite?" ON) option(XRT_FEATURE_COLOR_LOG "Enable logging in color on supported platforms" ON) +option(XRT_FEATURE_TRACING "Enable debug tracing on supported platforms" OFF) cmake_dependent_option(CMAKE_INTERPROCEDURAL_OPTIMIZATION "Enable inter-procedural (link-time) optimization" OFF "HAS_IPO" OFF) cmake_dependent_option(XRT_HAVE_WAYLAND "Enable Wayland support" ON "WAYLAND_FOUND AND WAYLAND_SCANNER_FOUND AND WAYLAND_PROTOCOLS_FOUND" OFF) @@ -335,6 +336,7 @@ message(STATUS "# FEATURE_OPENXR_LAYER_EQUIRECT2: ${XRT_FEATURE_OPENXR_ message(STATUS "# FEATURE_OPENXR_LAYER_EQUIRECT1: ${XRT_FEATURE_OPENXR_LAYER_EQUIRECT1}") message(STATUS "# FEATURE_STEAMVR_PLUGIN: ${XRT_FEATURE_STEAMVR_PLUGIN}") message(STATUS "# FEATURE_COLOR_LOG: ${XRT_FEATURE_COLOR_LOG}") +message(STATUS "# FEATURE_TRACING: ${XRT_FEATURE_TRACING}") message(STATUS "#") message(STATUS "# DRIVER_ANDROID: ${XRT_BUILD_DRIVER_ANDROID}") message(STATUS "# DRIVER_ARDUINO: ${XRT_BUILD_DRIVER_ARDUINO}") diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt index 303d3848a..3c485468c 100644 --- a/src/xrt/auxiliary/CMakeLists.txt +++ b/src/xrt/auxiliary/CMakeLists.txt @@ -141,6 +141,8 @@ set(UTIL_SOURCE_FILES util/u_time.h util/u_timing_render.c util/u_timing_render.h + util/u_trace_marker.c + util/u_trace_marker.h util/u_var.cpp util/u_var.h util/u_config_json.c diff --git a/src/xrt/auxiliary/meson.build b/src/xrt/auxiliary/meson.build index fe9eb30ad..570397a68 100644 --- a/src/xrt/auxiliary/meson.build +++ b/src/xrt/auxiliary/meson.build @@ -56,6 +56,8 @@ lib_aux_util = static_library( 'util/u_time.h', 'util/u_timing_render.c', 'util/u_timing_render.h', + 'util/u_trace_marker.c', + 'util/u_trace_marker.h', 'util/u_var.cpp', 'util/u_var.h', 'util/u_config_json.c', diff --git a/src/xrt/auxiliary/util/u_trace_marker.c b/src/xrt/auxiliary/util/u_trace_marker.c new file mode 100644 index 000000000..3af85d96c --- /dev/null +++ b/src/xrt/auxiliary/util/u_trace_marker.c @@ -0,0 +1,94 @@ +// Copyright 2020-2021, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Trace marking debugging code. + * @author Jakob Bornecrantz + * @ingroup aux_util + */ + + +// This needs to be first. +#define _GNU_SOURCE +#include +#include + +#include "xrt/xrt_compiler.h" + +#include "u_trace_marker.h" + +#include +#include +#include +#include +#include + + +#define TRACE_MARKER_FILENAME "/sys/kernel/tracing/trace_marker" + +int u_trace_xrt_fd = -1; +int u_trace_ipc_fd = -1; +int u_trace_oxr_fd = -1; +int u_trace_comp_fd = -1; + +void +u_tracer_maker_init(void) +{ + int fd = open(TRACE_MARKER_FILENAME, O_WRONLY); + + u_trace_oxr_fd = fd; + u_trace_ipc_fd = fd; + u_trace_xrt_fd = fd; + u_trace_comp_fd = fd; +} + +void +u_trace_enter(int fd, const char *func) +{ + if (fd < 0) { + return; + } + + char tmp[512]; + ssize_t len = snprintf(tmp, sizeof(tmp), "B %u %s", getpid(), func); + if (len > 0) { + len = write(fd, tmp, len); + } +} + +void +u_trace_leave(int fd, const char *func) +{ + if (fd < 0) { + return; + } + + char tmp[512]; + ssize_t len = snprintf(tmp, sizeof(tmp), "E %u %s", getpid(), func); + if (len > 0) { + len = write(fd, tmp, len); + } +} + +void +u_trace_data(int fd, enum u_trace_data_type type, void *data, size_t size) +{ + char tmp[1024 * 8]; + + ssize_t len = snprintf(tmp, sizeof(tmp), "r %u %u %u ", getpid(), type, (uint32_t)size); + if (len <= 0) { + return; + } + + for (size_t i = 0; i < size; i++) { + ssize_t ret = snprintf(tmp + (size_t)len, sizeof(tmp) - (size_t)len, "%02x", ((uint8_t *)data)[i]); + if (ret <= 0) { + return; + } + len += ret; + } + + if (len > 0) { + len = write(fd, tmp, len); + } +} diff --git a/src/xrt/auxiliary/util/u_trace_marker.h b/src/xrt/auxiliary/util/u_trace_marker.h new file mode 100644 index 000000000..1518d6776 --- /dev/null +++ b/src/xrt/auxiliary/util/u_trace_marker.h @@ -0,0 +1,130 @@ +// Copyright 2020-2021, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Trace marking debugging code. + * @author Jakob Bornecrantz + * @ingroup aux_util + */ + +#pragma once + +#include "xrt/xrt_compiler.h" +#include "xrt/xrt_config_os.h" +#include "xrt/xrt_config_build.h" + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +enum u_trace_data_type +{ + U_TRACE_DATA_TYPE_TIMING_FRAME, +}; + +void +u_tracer_maker_init(void); +void +u_trace_enter(int fd, const char *func); +void +u_trace_leave(int fd, const char *func); +void +u_trace_data(int fd, enum u_trace_data_type type, void *data, size_t size); + +extern int u_trace_xrt_fd; +extern int u_trace_ipc_fd; +extern int u_trace_oxr_fd; +extern int u_trace_comp_fd; + +#define XRT_TRACE_MARKER() U_TRACE_MARKER(u_trace_xrt_fd) +#define IPC_TRACE_MARKER() U_TRACE_MARKER(u_trace_ipc_fd) +#define OXR_TRACE_MARKER() U_TRACE_MARKER(u_trace_oxr_fd) +#define COMP_TRACE_MARKER() U_TRACE_MARKER(u_trace_comp_fd) +#define COMP_TRACE_DATA(type, data) U_TRACE_DATA(u_trace_comp_fd, type, data) + + +/* + * + * Functions implemented by other modules. + * + */ + +void +u_timing_frame_write_json(FILE *file, void *data); + +void +u_timing_frame_write_json_metadata(FILE *file); + + +/* + * + * When enabled. + * + */ + +#ifdef XRT_FEATURE_TRACING + +#ifndef XRT_OS_LINUX +#error "Tracing only supported on Linux" +#endif + +struct u_trace_scoped_struct +{ + const char *name; + int data; +}; + +static inline void +u_trace_scope_cleanup(struct u_trace_scoped_struct *data) +{ + u_trace_leave(data->data, data->name); +} + +#define U_TRACE_MARKER(fd) \ + struct u_trace_scoped_struct __attribute__((cleanup(u_trace_scope_cleanup))) \ + u_trace_marker_func_data = {__func__, fd}; \ + u_trace_enter(u_trace_marker_func_data.data, u_trace_marker_func_data.name) + + + +#define U_TRACE_DATA(fd, type, data) u_trace_data(fd, type, (void *)&(data), sizeof(data)) + + +#define U_TRACE_TARGET_INIT() \ + void __attribute__((constructor(101))) u_trace_maker_constructor(void); \ + \ + void u_trace_maker_constructor(void) \ + { \ + u_tracer_maker_init(); \ + } + + +#else // XRT_FEATURE_TRACING + + +/* + * + * When disabled. + * + */ + +#define U_TRACE_MARKER(fd) \ + do { \ + } while (false) + +#define U_TRACE_DATA(fd, type, data) \ + do { \ + } while (false) + +#define U_TRACE_TARGET_INIT() + +#endif // XRT_FEATURE_TRACING + + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/include/xrt/xrt_config_build.h.cmake_in b/src/xrt/include/xrt/xrt_config_build.h.cmake_in index 94f40d217..a6fc7e0ab 100644 --- a/src/xrt/include/xrt/xrt_config_build.h.cmake_in +++ b/src/xrt/include/xrt/xrt_config_build.h.cmake_in @@ -26,3 +26,5 @@ #cmakedefine XRT_FEATURE_OPENXR_LAYER_EQUIRECT1 #cmakedefine XRT_FEATURE_COLOR_LOG + +#cmakedefine XRT_FEATURE_TRACING