In the unlikely situation where a system sets its hardware clock
(CLOCK_REALTIME) to 0 (Epoch) after boot, the difference
monotonic - realtime
becomes negative.
Fixup this situation by returning a 0 offset in this case.
This ensures that trace viewer implementations (e.g. babeltrace) which
currently cannot handle the negative offset (known bug) still work with
the generated traces.
This patch should be applied to master and stable-2.7.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+/*
+ * The offset between monotonic and realtime clock can be negative if
+ * the system sets the REALTIME clock to 0 after boot.
+ * Currently handle this by flooring the offset at 0.
+ */
static
int measure_single_clock_offset(struct offset_sample *sample)
{
static
int measure_single_clock_offset(struct offset_sample *sample)
{
- uint64_t offset, monotonic[2], measure_delta, realtime;
+ uint64_t monotonic_avg, monotonic[2], measure_delta, realtime;
uint64_t tcf = trace_clock_freq();
uint64_t tcf = trace_clock_freq();
struct timespec rts = { 0, 0 };
int ret;
struct timespec rts = { 0, 0 };
int ret;
- offset = (monotonic[0] + monotonic[1]) >> 1;
+ monotonic_avg = (monotonic[0] + monotonic[1]) >> 1;
realtime = (uint64_t) rts.tv_sec * tcf;
if (tcf == NSEC_PER_SEC) {
realtime += rts.tv_nsec;
} else {
realtime += (uint64_t) rts.tv_nsec * tcf / NSEC_PER_SEC;
}
realtime = (uint64_t) rts.tv_sec * tcf;
if (tcf == NSEC_PER_SEC) {
realtime += rts.tv_nsec;
} else {
realtime += (uint64_t) rts.tv_nsec * tcf / NSEC_PER_SEC;
}
- offset = realtime - offset;
- sample->offset = offset;
+ offset = (int64_t) realtime - monotonic_avg;
+ sample->offset = max(offset, 0);
sample->measure_delta = measure_delta;
return 0;
}
sample->measure_delta = measure_delta;
return 0;
}