From: Mathieu Desnoyers Date: Fri, 24 Aug 2012 00:07:00 +0000 (-0400) Subject: Fix: handle clock offset with frequency different from 1GHz X-Git-Tag: v1.0.0-rc5~13 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=75d9ab4b8164f7b2012da916c5b36f1445e9ee09 Fix: handle clock offset with frequency different from 1GHz Signed-off-by: Mathieu Desnoyers --- diff --git a/formats/ctf/events-private.h b/formats/ctf/events-private.h index 6b3d5a17..6208e563 100644 --- a/formats/ctf/events-private.h +++ b/formats/ctf/events-private.h @@ -24,21 +24,7 @@ #include #include - -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 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; } diff --git a/include/Makefile.am b/include/Makefile.am index ae12713a..824be61b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 index 00000000..6fbc7c32 --- /dev/null +++ b/include/babeltrace/clock-internal.h @@ -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 + * Julien Desfossez + * + * 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 */ diff --git a/lib/trace-collection.c b/lib/trace-collection.c index 9bc5b1fc..1c78f280 100644 --- a/lib/trace-collection.c +++ b/lib/trace-collection.c @@ -24,6 +24,7 @@ #include #include #include /* for clocks */ +#include #include @@ -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