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.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
* taken at start of trace.
* Yes, this is only an approximation. Yes, we can (and will) do better
* in future versions.
* taken at start of trace.
* Yes, this is only an approximation. Yes, we can (and will) do better
* in future versions.
+ * Return 0 if offset is negative. It may happen if the system sets
+ * the REALTIME clock to 0 after boot.
*/
static
uint64_t measure_clock_offset(void)
{
*/
static
uint64_t measure_clock_offset(void)
{
- uint64_t offset, monotonic[2], realtime;
+ uint64_t monotonic_avg, monotonic[2], realtime;
uint64_t tcf = trace_clock_freq();
uint64_t tcf = trace_clock_freq();
struct timespec rts = { 0, 0 };
unsigned long flags;
struct timespec rts = { 0, 0 };
unsigned long flags;
monotonic[1] = trace_clock_read64();
local_irq_restore(flags);
monotonic[1] = trace_clock_read64();
local_irq_restore(flags);
- 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;
realtime = (uint64_t) rts.tv_sec * tcf;
if (tcf == NSEC_PER_SEC) {
realtime += rts.tv_nsec;
do_div(n, NSEC_PER_SEC);
realtime += n;
}
do_div(n, NSEC_PER_SEC);
realtime += n;
}
- offset = realtime - offset;
+ offset = (int64_t) realtime - monotonic_avg;
+ if (offset < 0)
+ return 0;