1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015 Intel Corporation 3 */ 4 5 6 #ifndef LTHREAD_TIMER_H_ 7 #define LTHREAD_TIMER_H_ 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 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 { 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; 31 32 clkns *= ns; 33 clkns /= 1e5; 34 35 return clkns; 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 64 #ifdef __cplusplus 65 } 66 #endif 67 68 #endif /* LTHREAD_TIMER_H_ */ 69