From fae85a8a40d2b64c2ed415d13c31bfbc87bf2710 Mon Sep 17 00:00:00 2001 From: Honggyu Kim Date: Sat, 11 May 2024 05:38:03 +0900 Subject: [PATCH] info: Add utc_offset info for external usage In some cases, there is a requirement to get the time offset between UTC time and our timestamp from the given clock source, CLOCK_MONOTONIC by default. This patch provides an additional info to provide UTC time offset in the output of uftrace info. This number can be used to make time adjustment easier for external tools such as tracecompass[1]. Closes: #1916 [1] https://eclipse.dev/tracecompass Requested-by: Matthew Khouzam Signed-off-by: Honggyu Kim --- cmds/dump.c | 2 +- cmds/info.c | 38 ++++++++++++++++++++++++++++++++++++++ uftrace.h | 3 +++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/cmds/dump.c b/cmds/dump.c index 8f41d72f7..02ed34313 100644 --- a/cmds/dump.c +++ b/cmds/dump.c @@ -540,7 +540,7 @@ static void dump_raw_header(struct uftrace_dump_ops *ops, struct uftrace_data *h const char *info_str[] = { "EXE_NAME", "EXE_BUILD_ID", "EXIT_STATUS", "CMDLINE", "CPUINFO", "MEMINFO", "OSINFO", "TASKINFO", "USAGEINFO", "LOADINFO", "ARG_SPEC", "RECORD_DATE", - "PATTERN_TYPE", "VERSION" }; + "PATTERN_TYPE", "VERSION", "UTC_OFFSET" }; pr_out("uftrace file header: magic = "); for (i = 0; i < UFTRACE_MAGIC_LEN; i++) diff --git a/cmds/info.c b/cmds/info.c index 2be7a91a8..c7cec1022 100644 --- a/cmds/info.c +++ b/cmds/info.c @@ -851,6 +851,41 @@ static int read_uftrace_version(void *arg) return 0; } +static int fill_utc_offset(void *arg) +{ + struct fill_handler_arg *fha = arg; + time_t current_time; + struct timespec ts; + long offset; + + time(¤t_time); + clock_gettime(clock_source, &ts); + + /* calculate time offset between UTC and clock_source. */ + offset = (long)difftime(current_time, ts.tv_sec); + + dprintf(fha->fd, "utc_offset:%ld\n", offset); + return 0; +} + +static int read_utc_offset(void *arg) +{ + struct read_handler_arg *rha = arg; + struct uftrace_data *handle = rha->handle; + struct uftrace_info *info = &handle->info; + char *buf = rha->buf; + + if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) + return -1; + + if (strncmp(buf, "utc_offset:", 11)) + return -1; + + info->utc_offset = copy_info_str(&buf[11]); + + return 0; +} + struct uftrace_info_handler { enum uftrace_info_bits bit; int (*handler)(void *arg); @@ -883,6 +918,7 @@ void fill_uftrace_info(uint64_t *info_mask, int fd, struct uftrace_opts *opts, i { RECORD_DATE, fill_record_date }, { PATTERN_TYPE, fill_pattern_type }, { VERSION, fill_uftrace_version }, + { UTC_OFFSET, fill_utc_offset }, }; for (i = 0; i < ARRAY_SIZE(fill_handlers); i++) { @@ -926,6 +962,7 @@ int read_uftrace_info(uint64_t info_mask, struct uftrace_data *handle) { RECORD_DATE, read_record_date }, { PATTERN_TYPE, read_pattern_type }, { VERSION, read_uftrace_version }, + { UTC_OFFSET, read_utc_offset }, }; memset(&handle->info, 0, sizeof(handle->info)); @@ -955,6 +992,7 @@ void clear_uftrace_info(struct uftrace_info *info) free(info->argspec); free(info->record_date); free(info->elapsed_time); + free(info->utc_offset); free(info->uftrace_version); free(info->retspec); free(info->autoarg); diff --git a/uftrace.h b/uftrace.h index 5c3c06d33..9d5aa8ee6 100644 --- a/uftrace.h +++ b/uftrace.h @@ -98,6 +98,7 @@ enum uftrace_info_bits { RECORD_DATE_BIT, PATTERN_TYPE_BIT, VERSION_BIT, + UTC_OFFSET_BIT, INFO_BIT_MAX, @@ -116,6 +117,7 @@ enum uftrace_info_bits { RECORD_DATE = (1U << RECORD_DATE_BIT), PATTERN_TYPE = (1U << PATTERN_TYPE_BIT), VERSION = (1U << VERSION_BIT), + UTC_OFFSET = (1U << UTC_OFFSET_BIT), }; struct uftrace_info { @@ -142,6 +144,7 @@ struct uftrace_info { double utime; char *record_date; char *elapsed_time; + char *utc_offset; long vctxsw; long ictxsw; long maxrss;