diff options
Diffstat (limited to 'tools/perf/arch/x86/util/tsc.c')
-rw-r--r-- | tools/perf/arch/x86/util/tsc.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c new file mode 100644 index 000000000000..b2519e49424f --- /dev/null +++ b/tools/perf/arch/x86/util/tsc.c | |||
@@ -0,0 +1,59 @@ | |||
1 | #include <stdbool.h> | ||
2 | #include <errno.h> | ||
3 | |||
4 | #include <linux/perf_event.h> | ||
5 | |||
6 | #include "../../perf.h" | ||
7 | #include "../../util/types.h" | ||
8 | #include "../../util/debug.h" | ||
9 | #include "tsc.h" | ||
10 | |||
11 | u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc) | ||
12 | { | ||
13 | u64 t, quot, rem; | ||
14 | |||
15 | t = ns - tc->time_zero; | ||
16 | quot = t / tc->time_mult; | ||
17 | rem = t % tc->time_mult; | ||
18 | return (quot << tc->time_shift) + | ||
19 | (rem << tc->time_shift) / tc->time_mult; | ||
20 | } | ||
21 | |||
22 | u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc) | ||
23 | { | ||
24 | u64 quot, rem; | ||
25 | |||
26 | quot = cyc >> tc->time_shift; | ||
27 | rem = cyc & ((1 << tc->time_shift) - 1); | ||
28 | return tc->time_zero + quot * tc->time_mult + | ||
29 | ((rem * tc->time_mult) >> tc->time_shift); | ||
30 | } | ||
31 | |||
32 | int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, | ||
33 | struct perf_tsc_conversion *tc) | ||
34 | { | ||
35 | bool cap_user_time_zero; | ||
36 | u32 seq; | ||
37 | int i = 0; | ||
38 | |||
39 | while (1) { | ||
40 | seq = pc->lock; | ||
41 | rmb(); | ||
42 | tc->time_mult = pc->time_mult; | ||
43 | tc->time_shift = pc->time_shift; | ||
44 | tc->time_zero = pc->time_zero; | ||
45 | cap_user_time_zero = pc->cap_user_time_zero; | ||
46 | rmb(); | ||
47 | if (pc->lock == seq && !(seq & 1)) | ||
48 | break; | ||
49 | if (++i > 10000) { | ||
50 | pr_debug("failed to get perf_event_mmap_page lock\n"); | ||
51 | return -EINVAL; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | if (!cap_user_time_zero) | ||
56 | return -EOPNOTSUPP; | ||
57 | |||
58 | return 0; | ||
59 | } | ||