[ltt-dev] [UST PATCH] Add LTTng clock source support

David Goulet david.goulet at polymtl.ca
Tue Jan 11 10:43:12 EST 2011


From: Julien Desfossez <julien.desfossez at polymtl.ca>

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 merge for analysis.

LTTng 0.240 or higher is needed for this new clock source.

Signed-off-by: David Goulet <david.goulet at polymtl.ca>
---
 include/ust/clock.h |  116 ++++++++++++++++++++++++++------------------------
 libust/tracectl.c   |   10 ++++
 2 files changed, 70 insertions(+), 56 deletions(-)

diff --git a/include/ust/clock.h b/include/ust/clock.h
index cb8a663..27e0347 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 <time.h>
 #include <sys/time.h>
@@ -37,78 +37,82 @@
 
    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
+	u64 lttng_ts;
+};
+#endif /* __i386__ || __x86_64__ */
 
-#if __i386 || __x86_64
+static int ust_clock_source;
 
-/* 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.
- */
+/* Choosing correct trace clock */
+#if __PPC__
 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;
+    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;
 }
 
-#endif /* __i386 || __x86_64 */
-
-#ifdef __PPC__
+#else   /* !__PPC__ */
 
 static __inline__ u64 trace_clock_read64(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;
+	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__ */
 
-#endif /* ! UST_TRACE_CLOCK_GENERIC */
-
 static __inline__ u64 trace_clock_frequency(void)
 {
-	return 1000000000LL;
+	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;
 }
 
 static __inline__ u32 trace_clock_freq_scale(void)
diff --git a/libust/tracectl.c b/libust/tracectl.c
index b783c76..f6d9ea1 100644
--- a/libust/tracectl.c
+++ b/libust/tracectl.c
@@ -39,6 +39,7 @@
 #include <ust/marker.h>
 #include <ust/tracepoint.h>
 #include <ust/tracectl.h>
+#include <ust/clock.h>
 #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;
+        WARN("UST traces will not be synchronized with LTTng traces");
+    }
+
 	autoprobe_val = getenv("UST_AUTOPROBE");
 	if (autoprobe_val) {
 		struct marker_iter iter;
-- 
1.7.3.5





More information about the lttng-dev mailing list