usage: timestamp-based-on-real-time=[on|off]
Instead of using number of instructions executed (which is per vcpu), we
use the wall time for timestamps. This is useful when tracing user mode
programs as well.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
contrib/plugins/uftrace.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/contrib/plugins/uftrace.c b/contrib/plugins/uftrace.c
index 58805b7884a..7bf658311b1 100644
--- a/contrib/plugins/uftrace.c
+++ b/contrib/plugins/uftrace.c
@@ -93,6 +93,7 @@ enum uftrace_record_type {
static struct qemu_plugin_scoreboard *score;
static uint64_t trace_sample;
static bool trace_privilege_level;
+static bool timestamp_based_on_real_time;
static CpuOps arch_ops;
static void uftrace_write_map(bool system_emulation)
@@ -445,7 +446,25 @@ static void cpu_set_new_sample(Cpu *cpu, uint64_t timestamp)
static uint64_t cpu_get_timestamp(const Cpu *cpu)
{
- return cpu->insn_count;
+ if (!timestamp_based_on_real_time) {
+ return cpu->insn_count;
+ }
+
+#ifdef _WIN32
+ /*
+ * On Windows, timespec_get is available only with UCRT, but not with
+ * MinGW64 environment. Simplify by using only gettimeofday on this
+ * platform.
+ */
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ uint64_t now_ns = tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
+#else
+ struct timespec ts;
+ timespec_get(&ts, TIME_UTC);
+ uint64_t now_ns = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
+#endif
+ return now_ns;
}
static uint8_t aarch64_num_privilege_levels(void)
@@ -849,6 +868,12 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
return -1;
}
+ } else if (g_strcmp0(tokens[0], "timestamp-based-on-real-time") == 0) {
+ if (!qemu_plugin_bool_parse(tokens[0], tokens[1],
+ ×tamp_based_on_real_time)) {
+ fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
+ return -1;
+ }
} else {
fprintf(stderr, "option parsing failed: %s\n", opt);
return -1;
--
2.47.2