]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2015 Intel Corporation | |
7c673cae FG |
3 | */ |
4 | ||
5 | ||
6 | #ifndef LTHREAD_TIMER_H_ | |
7 | #define LTHREAD_TIMER_H_ | |
8 | ||
11fdf7f2 TL |
9 | #ifdef __cplusplus |
10 | extern "C" { | |
11 | #endif | |
12 | ||
7c673cae FG |
13 | #include "lthread_int.h" |
14 | #include "lthread_sched.h" | |
15 | ||
16 | ||
17 | static inline uint64_t | |
18 | _ns_to_clks(uint64_t ns) | |
19 | { | |
11fdf7f2 TL |
20 | /* |
21 | * clkns needs to be divided by 1E9 to get ns clocks. However, | |
22 | * dividing by this first would lose a lot of accuracy. | |
23 | * Dividing after a multiply by ns, could cause overflow of | |
24 | * uint64_t if ns is about 5 seconds [if we assume a max tsc | |
25 | * rate of 4GHz]. Therefore we first divide by 1E4, then | |
26 | * multiply and finally divide by 1E5. This allows ns to be | |
27 | * values many hours long, without overflow, while still keeping | |
28 | * reasonable accuracy. | |
29 | */ | |
30 | uint64_t clkns = rte_get_tsc_hz() / 1e4; | |
7c673cae FG |
31 | |
32 | clkns *= ns; | |
11fdf7f2 TL |
33 | clkns /= 1e5; |
34 | ||
35 | return clkns; | |
7c673cae FG |
36 | } |
37 | ||
38 | ||
39 | static inline void | |
40 | _timer_start(struct lthread *lt, uint64_t clks) | |
41 | { | |
42 | if (clks > 0) { | |
43 | DIAG_EVENT(lt, LT_DIAG_LTHREAD_TMR_START, <->tim, clks); | |
44 | rte_timer_init(<->tim); | |
45 | rte_timer_reset(<->tim, | |
46 | clks, | |
47 | SINGLE, | |
48 | rte_lcore_id(), | |
49 | _sched_timer_cb, | |
50 | (void *)lt); | |
51 | } | |
52 | } | |
53 | ||
54 | ||
55 | static inline void | |
56 | _timer_stop(struct lthread *lt) | |
57 | { | |
58 | if (lt != NULL) { | |
59 | DIAG_EVENT(lt, LT_DIAG_LTHREAD_TMR_DELETE, <->tim, 0); | |
60 | rte_timer_stop(<->tim); | |
61 | } | |
62 | } | |
63 | ||
11fdf7f2 TL |
64 | #ifdef __cplusplus |
65 | } | |
66 | #endif | |
7c673cae FG |
67 | |
68 | #endif /* LTHREAD_TIMER_H_ */ |