From: Julien Desfossez Date: Wed, 12 Jan 2011 08:36:37 +0000 (+0100) Subject: At runtime, UST checks if the LTTng clock source is available X-Git-Tag: v0.10~2 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=9c6bb08180ab0a65bbf3d47247a9d36e257fa44a;p=ust.git At runtime, UST checks if the LTTng clock source is available If not, CLOCK_MONOTONIC is the default fallback. This makes UST use the LTTng kernel clock source. With this clock support, LTTng and UST traces are perfectly synchronize. Traces from these two tracer can be merged for analysis. LTTng 0.240 or higher is needed for this new clock source. Signed-off-by: Julien Desfossez Signed-off-by: David Goulet Acked-by: Nils Carlson --- diff --git a/include/ust/clock.h b/include/ust/clock.h index cb8a663..ac0a2d5 100644 --- a/include/ust/clock.h +++ b/include/ust/clock.h @@ -15,8 +15,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef UST_CLOCK_H -#define UST_CLOCK_H +#ifndef _UST_CLOCK_H +#define _UST_CLOCK_H #include #include @@ -29,56 +29,30 @@ - gettimeofday() clock Microbenchmarks on Linux 2.6.30 on Core2 Duo 3GHz (functions are inlined): - Calls (100000000) to tsc(): 4004035641 cycles or 40 cycles/call - Calls (100000000) to gettimeofday(): 9723158352 cycles or 97 cycles/call + Calls (100000000) to tsc(): 4004035641 cycles or 40 cycles/call + Calls (100000000) to gettimeofday(): 9723158352 cycles or 97 cycles/call For merging traces with the kernel, a time source compatible with that of the kernel is necessary. Instead of gettimeofday(), we are now using clock_gettime for better precision and monotonicity. - */ -#define TRACE_CLOCK_GENERIC -#ifdef TRACE_CLOCK_GENERIC - -static __inline__ u64 trace_clock_read64(void) -{ +#if __i386__ || __x86_64__ +/* Only available for x86 arch */ +#define CLOCK_TRACE_FREQ 14 +#define CLOCK_TRACE 15 +union lttng_timespec { struct timespec ts; - u64 retval; - - clock_gettime(CLOCK_MONOTONIC, &ts); - retval = ts.tv_sec; - retval *= 1000000000; - retval += ts.tv_nsec; - - return retval; -} - -#else - -#if __i386 || __x86_64 - -/* WARNING: Make sure to set frequency and scaling functions that will not - * result in lttv timestamps (sec.nsec) with seconds greater than 2**32-1. - */ -static __inline__ u64 trace_clock_read64(void) -{ - uint32_t low; - uint32_t high; - uint64_t retval; - __asm__ volatile ("rdtsc\n" : "=a" (low), "=d" (high)); - - retval = high; - retval <<= 32; - return retval | low; -} - -#endif /* __i386 || __x86_64 */ + u64 lttng_ts; +}; +#endif /* __i386__ || __x86_64__ */ -#ifdef __PPC__ +static int ust_clock_source; +/* Choosing correct trace clock */ +#if __PPC__ static __inline__ u64 trace_clock_read64(void) { unsigned long tb_l; @@ -93,8 +67,8 @@ static __inline__ u64 trace_clock_read64(void) "mftbu %[rhigh2]\n\t" "cmpw %[rhigh],%[rhigh2]\n\t" "bne 1b\n\t" - : [rhigh] "=r" (tb_h), [rhigh2] "=r" (tb_h2), [rlow] "=r" (tb_l)); - + : [rhigh] "=r" (tb_h), [rhigh2] "=r" (tb_h2), [rlow] "=r" (tb_l)); + tb = tb_h; tb <<= 32; tb |= tb_l; @@ -102,12 +76,42 @@ static __inline__ u64 trace_clock_read64(void) return tb; } -#endif /* __PPC__ */ +#else /* !__PPC__ */ -#endif /* ! UST_TRACE_CLOCK_GENERIC */ +static __inline__ u64 trace_clock_read64(void) +{ + struct timespec ts; + u64 retval; + union lttng_timespec *lts = (union lttng_timespec *) &ts; + + clock_gettime(ust_clock_source, &ts); + /* + * Clock source can change when loading the binary (tracectl.c) + * so we must check if the clock source has changed before + * returning the correct value + */ + if (likely(ust_clock_source == CLOCK_TRACE)) { + retval = lts->lttng_ts; + } else { /* CLOCK_MONOTONIC */ + retval = ts.tv_sec; + retval *= 1000000000; + retval += ts.tv_nsec; + } + + return retval; +} + +#endif /* __PPC__ */ static __inline__ u64 trace_clock_frequency(void) { + struct timespec ts; + union lttng_timespec *lts = (union lttng_timespec *) &ts; + + if (likely(ust_clock_source == CLOCK_TRACE)) { + clock_gettime(CLOCK_TRACE_FREQ, &ts); + return lts->lttng_ts; + } return 1000000000LL; } @@ -116,4 +120,4 @@ static __inline__ u32 trace_clock_freq_scale(void) return 1; } -#endif /* UST_CLOCK_H */ +#endif /* _UST_CLOCK_H */ diff --git a/libust/tracectl.c b/libust/tracectl.c index b783c76..4f016bb 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "tracer.h" #include "usterr.h" #include "ustcomm.h" @@ -1262,6 +1263,15 @@ static void __attribute__((constructor)) init() create_listener(); + /* Get clock the clock source type */ + struct timespec ts; + /* Default clock source */ + ust_clock_source = CLOCK_TRACE; + if (clock_gettime(ust_clock_source, &ts) != 0) { + ust_clock_source = CLOCK_MONOTONIC; + DBG("UST traces will not be synchronized with LTTng traces"); + } + autoprobe_val = getenv("UST_AUTOPROBE"); if (autoprobe_val) { struct marker_iter iter;