Fix: handle clock offset with frequency different from 1GHz
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 24 Aug 2012 00:07:00 +0000 (20:07 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 24 Aug 2012 00:07:00 +0000 (20:07 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/events-private.h
include/Makefile.am
include/babeltrace/clock-internal.h [new file with mode: 0644]
lib/trace-collection.c

index 6b3d5a177f3756d9b7436316117de82e11daecd2..6208e563d2315f94994f88c183041bacc8d3d65c 100644 (file)
 
 #include <babeltrace/ctf/events.h>
 #include <babeltrace/ctf-ir/metadata.h>
-
-static inline
-uint64_t ctf_get_timestamp_raw(struct ctf_stream_definition *stream,
-                       uint64_t timestamp)
-{
-       uint64_t ts_nsec;
-
-       if (stream->current_clock->freq == 1000000000ULL) {
-               ts_nsec = timestamp;
-       } else {
-               ts_nsec = (uint64_t) ((double) timestamp * 1000000000.0
-                               / (double) stream->current_clock->freq);
-       }
-       return ts_nsec;
-}
+#include <babeltrace/clock-internal.h>
 
 static inline
 uint64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream,
@@ -49,7 +35,7 @@ uint64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream,
        struct trace_collection *tc = trace->collection;
        uint64_t tc_offset = tc->single_clock_offset_avg;
 
-       ts_nsec = ctf_get_timestamp_raw(stream, timestamp);
+       ts_nsec = clock_cycles_to_ns(stream->current_clock, timestamp);
        ts_nsec += tc_offset;   /* Add offset */
        return ts_nsec;
 }
index ae12713a431d821ae0fe1b17f9e115916085a7d0..824be61b34a05b678df163b36597fdde84382806 100644 (file)
@@ -16,6 +16,7 @@ noinst_HEADERS = \
        babeltrace/align.h \
        babeltrace/babeltrace-internal.h \
        babeltrace/bitfield.h \
+       babeltrace/clock-internal.h \
        babeltrace/compiler.h \
        babeltrace/context-internal.h \
        babeltrace/iterator-internal.h \
diff --git a/include/babeltrace/clock-internal.h b/include/babeltrace/clock-internal.h
new file mode 100644 (file)
index 0000000..6fbc7c3
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _BABELTRACE_CLOCK_INTERNAL_H
+#define _BABELTRACE_CLOCK_INTERNAL_H
+
+/*
+ * BabelTrace
+ *
+ * clocks header (internal)
+ *
+ * Copyright 2012 EfficiOS Inc. and Linux Foundation
+ *
+ * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *         Julien Desfossez <julien.desfossez@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+
+static inline
+uint64_t clock_cycles_to_ns(struct ctf_clock *clock, uint64_t cycles)
+{
+       if (clock->freq == 1000000000ULL) {
+               /* 1GHZ freq, no need to scale cycles value */
+               return cycles;
+       } else {
+               return (double) cycles * 1000000000.0
+                               / (double) clock->freq;
+       }
+}
+
+#endif /* _BABELTRACE_CLOCK_INTERNAL_H */
index 9bc5b1fcc8b0ecc543dd65b7a67734f4c44c8968..1c78f280fe0bcb128d3da85dbdfdf5a0e5daa6b4 100644 (file)
@@ -24,6 +24,7 @@
 #include <babeltrace/ctf-text/types.h>
 #include <babeltrace/trace-collection.h>
 #include <babeltrace/ctf-ir/metadata.h>        /* for clocks */
+#include <babeltrace/clock-internal.h>
 
 #include <inttypes.h>
 
@@ -63,6 +64,19 @@ static void check_clock_match(gpointer key, gpointer value, gpointer user_data)
        }
 }
 
+/*
+ * Note: if using a frequency different from 1GHz for clock->offset, it
+ * is recommended to express the seconds in offset_s, otherwise there
+ * will be a loss of precision caused by the limited size of the double
+ * mantissa.
+ */
+static
+uint64_t clock_offset_ns(struct ctf_clock *clock)
+{
+       return clock->offset_s * 1000000000ULL
+                       + clock_cycles_to_ns(clock, clock->offset);
+}
+
 static void clock_add(gpointer key, gpointer value, gpointer user_data)
 {
        struct clock_match *clock_match = user_data;
@@ -88,8 +102,7 @@ static void clock_add(gpointer key, gpointer value, gpointer user_data)
                                fprintf(stderr, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
                        }
                        if (!clock_match->tc->offset_nr) {
-                               clock_match->tc->offset_first =
-                                       (t_clock->offset_s * 1000000000ULL) + t_clock->offset;
+                               clock_match->tc->offset_first = clock_offset_ns(t_clock);
                                clock_match->tc->delta_offset_first_sum = 0;
                                clock_match->tc->offset_nr++;
                                clock_match->tc->single_clock_offset_avg =
@@ -105,23 +118,18 @@ static void clock_add(gpointer key, gpointer value, gpointer user_data)
                         * Check that the offsets match. If not, warn
                         * the user that we do an arbitrary choice.
                         */
-                       diff_ns = tc_clock->offset_s;
-                       diff_ns -= t_clock->offset_s;
-                       diff_ns *= 1000000000ULL;
-                       diff_ns += tc_clock->offset;
-                       diff_ns -= t_clock->offset;
+                       diff_ns = clock_offset_ns(tc_clock) - clock_offset_ns(t_clock);
                        printf_debug("Clock \"%s\" offset between traces has a delta of %" PRIu64 " ns.",
                                g_quark_to_string(tc_clock->name),
                                diff_ns < 0 ? -diff_ns : diff_ns);
-                       if (diff_ns > 10000) {
+                       if (diff_ns > 10000 || diff_ns < -10000) {
                                fprintf(stderr, "[warning] Clock \"%s\" offset differs between traces (delta %" PRIu64 " ns). Using average.\n",
                                        g_quark_to_string(tc_clock->name),
                                        diff_ns < 0 ? -diff_ns : diff_ns);
                        }
                        /* Compute average */
                        clock_match->tc->delta_offset_first_sum +=
-                               (t_clock->offset_s * 1000000000ULL) + t_clock->offset
-                               - clock_match->tc->offset_first;
+                               clock_offset_ns(t_clock) - clock_match->tc->offset_first;
                        clock_match->tc->offset_nr++;
                        clock_match->tc->single_clock_offset_avg =
                                clock_match->tc->offset_first
This page took 0.03845 seconds and 4 git commands to generate.