Commit | Line | Data |
---|---|---|
4d599388 FD |
1 | /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) |
2 | * | |
3 | * src/clock-utils.h | |
4 | * | |
5 | * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
6 | * Copyright (C) 2022 Francis Deslauriers <francis.deslauriers@efficios.com> | |
7 | */ | |
8 | ||
9 | /* | |
10 | * Approximation of NTP time of day to clock monotonic correlation, | |
11 | * taken at start of trace. | |
12 | * Yes, this is only an approximation. Yes, we can (and will) do better | |
13 | * in future versions. | |
14 | * This function may return a negative offset. It may happen if the | |
15 | * system sets the REALTIME clock to 0 after boot. | |
16 | * | |
17 | * Use 64bit timespec on kernels that have it, this makes 32bit arch | |
18 | * y2038 compliant. | |
19 | */ | |
20 | ||
21 | #include <linux/types.h> | |
22 | ||
23 | #include <wrapper/time.h> | |
24 | #include <wrapper/trace-clock.h> | |
25 | ||
26 | int64_t trace_clock_offset(void) | |
27 | { | |
28 | uint64_t monotonic_avg, monotonic[2], realtime; | |
29 | uint64_t tcf = trace_clock_freq(); | |
30 | int64_t offset; | |
31 | unsigned long flags; | |
32 | #ifdef LTTNG_KERNEL_HAS_TIMESPEC64 | |
33 | struct timespec64 rts = { 0, 0 }; | |
34 | #else | |
35 | struct timespec rts = { 0, 0 }; | |
36 | #endif | |
37 | ||
38 | /* Disable interrupts to increase correlation precision. */ | |
39 | local_irq_save(flags); | |
40 | monotonic[0] = trace_clock_read64(); | |
41 | #ifdef LTTNG_KERNEL_HAS_TIMESPEC64 | |
42 | ktime_get_real_ts64(&rts); | |
43 | #else | |
44 | getnstimeofday(&rts); | |
45 | #endif | |
46 | monotonic[1] = trace_clock_read64(); | |
47 | local_irq_restore(flags); | |
48 | ||
49 | monotonic_avg = (monotonic[0] + monotonic[1]) >> 1; | |
50 | realtime = (uint64_t)rts.tv_sec * tcf; | |
51 | if (tcf == NSEC_PER_SEC) { | |
52 | realtime += rts.tv_nsec; | |
53 | } else { | |
54 | uint64_t n = rts.tv_nsec * tcf; | |
55 | ||
56 | do_div(n, NSEC_PER_SEC); | |
57 | realtime += n; | |
58 | } | |
59 | offset = (int64_t)realtime - monotonic_avg; | |
60 | return offset; | |
61 | } |