]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2015 Intel Corporation | |
7c673cae FG |
3 | */ |
4 | ||
5 | #ifndef _RTE_TIME_H_ | |
6 | #define _RTE_TIME_H_ | |
7 | ||
8 | #include <stdint.h> | |
9 | #include <time.h> | |
10 | ||
11 | #define NSEC_PER_SEC 1000000000L | |
12 | ||
13 | /** | |
14 | * Structure to hold the parameters of a running cycle counter to assist | |
15 | * in converting cycles to nanoseconds. | |
16 | */ | |
17 | struct rte_timecounter { | |
18 | /** Last cycle counter value read. */ | |
19 | uint64_t cycle_last; | |
20 | /** Nanoseconds count. */ | |
21 | uint64_t nsec; | |
22 | /** Bitmask separating nanosecond and sub-nanoseconds. */ | |
23 | uint64_t nsec_mask; | |
24 | /** Sub-nanoseconds count. */ | |
25 | uint64_t nsec_frac; | |
9f95a23c | 26 | /** Bitmask for two's complement subtraction of non-64 bit counters. */ |
7c673cae FG |
27 | uint64_t cc_mask; |
28 | /** Cycle to nanosecond divisor (power of two). */ | |
29 | uint32_t cc_shift; | |
30 | }; | |
31 | ||
32 | /** | |
33 | * Converts cyclecounter cycles to nanoseconds. | |
34 | */ | |
35 | static inline uint64_t | |
36 | rte_cyclecounter_cycles_to_ns(struct rte_timecounter *tc, uint64_t cycles) | |
37 | { | |
38 | uint64_t ns; | |
39 | ||
40 | /* Add fractional nanoseconds. */ | |
41 | ns = cycles + tc->nsec_frac; | |
42 | tc->nsec_frac = ns & tc->nsec_mask; | |
43 | ||
44 | /* Shift to get only nanoseconds. */ | |
45 | return ns >> tc->cc_shift; | |
46 | } | |
47 | ||
48 | /** | |
49 | * Update the internal nanosecond count in the structure. | |
50 | */ | |
51 | static inline uint64_t | |
52 | rte_timecounter_update(struct rte_timecounter *tc, uint64_t cycle_now) | |
53 | { | |
54 | uint64_t cycle_delta, ns_offset; | |
55 | ||
56 | /* Calculate the delta since the last call. */ | |
57 | if (tc->cycle_last <= cycle_now) | |
58 | cycle_delta = (cycle_now - tc->cycle_last) & tc->cc_mask; | |
59 | else | |
60 | /* Handle cycle counts that have wrapped around . */ | |
61 | cycle_delta = (~(tc->cycle_last - cycle_now) & tc->cc_mask) + 1; | |
62 | ||
63 | /* Convert to nanoseconds. */ | |
64 | ns_offset = rte_cyclecounter_cycles_to_ns(tc, cycle_delta); | |
65 | ||
66 | /* Store current cycle counter for next call. */ | |
67 | tc->cycle_last = cycle_now; | |
68 | ||
69 | /* Update the nanosecond count. */ | |
70 | tc->nsec += ns_offset; | |
71 | ||
72 | return tc->nsec; | |
73 | } | |
74 | ||
75 | /** | |
76 | * Convert from timespec structure into nanosecond units. | |
77 | */ | |
78 | static inline uint64_t | |
79 | rte_timespec_to_ns(const struct timespec *ts) | |
80 | { | |
81 | return ((uint64_t) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; | |
82 | } | |
83 | ||
84 | /** | |
85 | * Convert from nanosecond units into timespec structure. | |
86 | */ | |
87 | static inline struct timespec | |
88 | rte_ns_to_timespec(uint64_t nsec) | |
89 | { | |
90 | struct timespec ts = {0, 0}; | |
91 | ||
92 | if (nsec == 0) | |
93 | return ts; | |
94 | ||
95 | ts.tv_sec = nsec / NSEC_PER_SEC; | |
96 | ts.tv_nsec = nsec % NSEC_PER_SEC; | |
97 | ||
98 | return ts; | |
99 | } | |
100 | ||
101 | #endif /* _RTE_TIME_H_ */ |