#define NR_CLOCK_OFFSET_SAMPLES 10
struct offset_sample {
- uint64_t offset; /* correlation offset */
+ int64_t offset; /* correlation offset */
uint64_t measure_delta; /* lower is better */
};
);
}
+/*
+ * The offset between monotonic and realtime clock can be negative if
+ * the system sets the REALTIME clock to 0 after boot.
+ */
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();
struct timespec rts = { 0, 0 };
int ret;
*/
return 0;
}
- 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;
}
- offset = realtime - offset;
- sample->offset = offset;
+ sample->offset = (int64_t) realtime - monotonic_avg;
sample->measure_delta = measure_delta;
return 0;
}
* Approximation of NTP time of day to clock monotonic correlation,
* taken at start of trace. Keep the measurement that took the less time
* to complete, thus removing imprecision caused by preemption.
+ * May return a negative offset.
*/
static
-uint64_t measure_clock_offset(void)
+int64_t measure_clock_offset(void)
{
int i;
struct offset_sample offset_best_sample = {
" description = \"%s\";\n"
" freq = %" PRIu64 "; /* Frequency, in Hz */\n"
" /* clock value offset from Epoch is: offset * (1/freq) */\n"
- " offset = %" PRIu64 ";\n"
+ " offset = %" PRId64 ";\n"
"};\n\n",
trace_clock_description(),
trace_clock_freq(),