X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=include%2Fust%2Fclock.h;h=22d2efc65c9666905ff896d0fac4c89a8bbd2462;hb=772d939d19475d995bcd7dda6924f7d7a5bf3ae1;hp=d4b6a9ddc1e2768a219beed14d0c6336b4d58b13;hpb=518d7abb8e3720433c611499f704c3bd9d554102;p=ust.git diff --git a/include/ust/clock.h b/include/ust/clock.h index d4b6a9d..22d2efc 100644 --- a/include/ust/clock.h +++ b/include/ust/clock.h @@ -15,9 +15,10 @@ * 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 #include @@ -28,88 +29,73 @@ - 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 +/* Only available for x86 arch */ +#define CLOCK_TRACE_FREQ 14 +#define CLOCK_TRACE 15 +union lttng_timespec { + struct timespec ts; + u64 lttng_ts; +}; + +extern int ust_clock_source; + +/* Choosing correct trace clock */ static __inline__ u64 trace_clock_read64(void) { - struct timeval tv; + struct timespec ts; u64 retval; - - gettimeofday(&tv, NULL); - retval = tv.tv_sec; - retval *= 1000000; - retval += tv.tv_usec; + 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; } -#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 */ - -#ifdef __PPC__ - -static __inline__ u64 trace_clock_read64(void) +#if __i386__ || __x86_64__ +static __inline__ u64 trace_clock_frequency(void) { - unsigned long tb_l; - unsigned long tb_h; - unsigned long tb_h2; - u64 tb; - - __asm__ ( - "1:\n\t" - "mftbu %[rhigh]\n\t" - "mftb %[rlow]\n\t" - "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)); - - tb = tb_h; - tb <<= 32; - tb |= tb_l; - - return tb; + 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; } - -#endif /* __PPC__ */ - -#endif /* ! UST_TRACE_CLOCK_GENERIC */ - +#else /* #if __i386__ || __x86_64__ */ static __inline__ u64 trace_clock_frequency(void) { - return 1000000LL; + return 1000000000LL; } +#endif /* #else #if __i386__ || __x86_64__ */ static __inline__ u32 trace_clock_freq_scale(void) { return 1; } -#endif /* UST_CLOCK_H */ +#endif /* _UST_CLOCK_H */