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