Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2010-2014 Intel Corporation 3 : : */ 4 : : 5 : : #include <stdio.h> 6 : : #include <inttypes.h> 7 : : 8 : : #include <rte_common.h> 9 : : #include <rte_log.h> 10 : : #include <rte_cycles.h> 11 : : #include <rte_pause.h> 12 : : #include <rte_eal.h> 13 : : 14 : : #include <eal_export.h> 15 : : #include "eal_private.h" 16 : : #include "eal_memcfg.h" 17 : : 18 : : /* The frequency of the RDTSC timer resolution */ 19 : : static uint64_t eal_tsc_resolution_hz; 20 : : 21 : : /* Pointer to user delay function */ 22 : : RTE_EXPORT_SYMBOL(rte_delay_us) 23 : : void (*rte_delay_us)(unsigned int) = NULL; 24 : : 25 : : RTE_EXPORT_SYMBOL(rte_delay_us_block) 26 : : void 27 : 485693 : rte_delay_us_block(unsigned int us) 28 : : { 29 : : const uint64_t start = rte_get_timer_cycles(); 30 : 496984 : const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; 31 [ + + ]: 148738416 : while ((rte_get_timer_cycles() - start) < ticks) 32 : : rte_pause(); 33 : 434846 : } 34 : : 35 : : RTE_EXPORT_SYMBOL(rte_get_tsc_hz) 36 : : uint64_t 37 : 500412 : rte_get_tsc_hz(void) 38 : : { 39 : 500412 : return eal_tsc_resolution_hz; 40 : : } 41 : : 42 : : static uint64_t 43 : 0 : estimate_tsc_freq(void) 44 : : { 45 : : #define CYC_PER_10MHZ 1E7 46 : 0 : EAL_LOG(WARNING, "WARNING: TSC frequency estimated roughly" 47 : : " - clock timings may be less accurate."); 48 : : /* assume that the rte_delay_us_sleep() will sleep for 1 second */ 49 : : uint64_t start = rte_rdtsc(); 50 : 0 : rte_delay_us_sleep(US_PER_S); 51 : : /* Round up to 10Mhz. 1E7 ~ 10Mhz */ 52 [ # # ]: 0 : return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ); 53 : : } 54 : : 55 : : void 56 : 180 : set_tsc_freq(void) 57 : : { 58 : 180 : struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; 59 : : uint64_t freq; 60 : : 61 [ + + ]: 180 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) { 62 : : /* 63 : : * Just use the primary process calculated TSC rate in any 64 : : * secondary process. It avoids any unnecessary overhead on 65 : : * systems where arch-specific frequency detection is not 66 : : * available. 67 : : */ 68 : 25 : eal_tsc_resolution_hz = mcfg->tsc_hz; 69 : 25 : return; 70 : : } 71 : : 72 : 155 : freq = get_tsc_freq_arch(); 73 : 155 : freq = get_tsc_freq(freq); 74 [ - + ]: 155 : if (!freq) 75 : 0 : freq = estimate_tsc_freq(); 76 : : 77 : 155 : EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000); 78 : 155 : eal_tsc_resolution_hz = freq; 79 : 155 : mcfg->tsc_hz = freq; 80 : : } 81 : : 82 : : RTE_EXPORT_SYMBOL(rte_delay_us_callback_register) 83 : 254 : void rte_delay_us_callback_register(void (*userfunc)(unsigned int)) 84 : : { 85 : 254 : rte_delay_us = userfunc; 86 : 254 : } 87 : : 88 : 252 : RTE_INIT(rte_timer_init) 89 : : { 90 : : /* set rte_delay_us_block as a delay function */ 91 : 252 : rte_delay_us_callback_register(rte_delay_us_block); 92 : 252 : }