From fc0bb9faabea638797e5436a93175224b831ca6e Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 1 Oct 2014 17:59:20 -0400 Subject: [PATCH] Implement UST clock override plugin support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- src/bin/lttng-sessiond/ust-clock.h | 106 ++++++++++++++++++++++++-- src/bin/lttng-sessiond/ust-metadata.c | 22 ++++-- 2 files changed, 114 insertions(+), 14 deletions(-) diff --git a/src/bin/lttng-sessiond/ust-clock.h b/src/bin/lttng-sessiond/ust-clock.h index 7d9c99a66..849373763 100644 --- a/src/bin/lttng-sessiond/ust-clock.h +++ b/src/bin/lttng-sessiond/ust-clock.h @@ -25,12 +25,26 @@ #include #include #include -#include +#include +#include +#include #include /* TRACE CLOCK */ +struct lttng_trace_clock { + uint64_t (*read64)(void); + uint64_t (*freq)(void); + int (*uuid)(char *uuid); + const char *(*name)(void); + const char *(*description)(void); +}; + +extern struct lttng_trace_clock *lttng_trace_clock; + +void lttng_ust_clock_init(void); + /* * Currently using the kernel MONOTONIC clock, waiting for kernel-side * LTTng to implement mmap'd trace clock. @@ -39,7 +53,7 @@ /* Choosing correct trace clock */ static __inline__ -uint64_t trace_clock_read64(void) +uint64_t trace_clock_read64_monotonic(void) { struct timespec ts; @@ -48,13 +62,13 @@ uint64_t trace_clock_read64(void) } static __inline__ -uint64_t trace_clock_freq(void) +uint64_t trace_clock_freq_monotonic(void) { return 1000000000ULL; } static __inline__ -int trace_clock_uuid(char *uuid) +int trace_clock_uuid_monotonic(char *uuid) { int ret = 0; size_t len; @@ -69,15 +83,93 @@ int trace_clock_uuid(char *uuid) if (!fp) { return -ENOENT; } - len = fread(uuid, 1, UUID_STR_LEN - 1, fp); - if (len < UUID_STR_LEN - 1) { + len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp); + if (len < LTTNG_UST_UUID_STR_LEN - 1) { ret = -EINVAL; goto end; } - uuid[UUID_STR_LEN - 1] = '\0'; + uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0'; end: fclose(fp); return ret; } +static __inline__ +const char *trace_clock_name_monotonic(void) +{ + return "monotonic"; +} + +static __inline__ +const char *trace_clock_description_monotonic(void) +{ + return "Monotonic Clock"; +} + +static __inline__ +uint64_t trace_clock_read64(void) +{ + struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock); + + if (caa_likely(!ltc)) { + return trace_clock_read64_monotonic(); + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + return ltc->read64(); + } +} + +static __inline__ +uint64_t trace_clock_freq(void) +{ + struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock); + + if (!ltc) { + return trace_clock_freq_monotonic(); + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + return ltc->freq(); + } +} + +static __inline__ +int trace_clock_uuid(char *uuid) +{ + struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock); + + cmm_read_barrier_depends(); /* load ltc before content */ + /* Use default UUID cb when NULL */ + if (!ltc || !ltc->uuid) { + return trace_clock_uuid_monotonic(uuid); + } else { + return ltc->uuid(uuid); + } +} + +static __inline__ +const char *trace_clock_name(void) +{ + struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock); + + if (!ltc) { + return trace_clock_name_monotonic(); + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + return ltc->name(); + } +} + +static __inline__ +const char *trace_clock_description(void) +{ + struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock); + + if (!ltc) { + return trace_clock_description_monotonic(); + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + return ltc->description(); + } +} + #endif /* _UST_CLOCK_H */ diff --git a/src/bin/lttng-sessiond/ust-metadata.c b/src/bin/lttng-sessiond/ust-metadata.c index f4f273b16..b67921ef8 100644 --- a/src/bin/lttng-sessiond/ust-metadata.c +++ b/src/bin/lttng-sessiond/ust-metadata.c @@ -524,6 +524,7 @@ static int measure_single_clock_offset(struct offset_sample *sample) { uint64_t offset, monotonic[2], measure_delta, realtime; + uint64_t tcf = trace_clock_freq(); struct timespec rts = { 0, 0 }; int ret; @@ -544,6 +545,9 @@ int measure_single_clock_offset(struct offset_sample *sample) offset = (monotonic[0] + monotonic[1]) >> 1; realtime = (uint64_t) rts.tv_sec * 1000000000ULL; realtime += rts.tv_nsec; + if (tcf != 1000000000ULL) { + realtime /= 1000000000ULL / tcf; + } offset = realtime - offset; sample->offset = offset; sample->measure_delta = measure_delta; @@ -685,8 +689,8 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, ret = lttng_metadata_printf(session, "clock {\n" - " name = %s;\n", - "monotonic" + " name = \"%s\";\n", + trace_clock_name() ); if (ret) goto end; @@ -701,11 +705,12 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, } ret = lttng_metadata_printf(session, - " description = \"Monotonic Clock\";\n" + " description = \"%s\";\n" " freq = %" PRIu64 "; /* Frequency, in Hz */\n" " /* clock value offset from Epoch is: offset * (1/freq) */\n" " offset = %" PRIu64 ";\n" "};\n\n", + trace_clock_description(), trace_clock_freq(), measure_clock_offset() ); @@ -715,20 +720,23 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, ret = lttng_metadata_printf(session, "typealias integer {\n" " size = 27; align = 1; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint27_clock_monotonic_t;\n" "\n" "typealias integer {\n" " size = 32; align = %u; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint32_clock_monotonic_t;\n" "\n" "typealias integer {\n" " size = 64; align = %u; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint64_clock_monotonic_t;\n\n", + trace_clock_name(), session->uint32_t_alignment, - session->uint64_t_alignment + trace_clock_name(), + session->uint64_t_alignment, + trace_clock_name() ); if (ret) goto end; -- 2.34.1