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_private.h" 15 : : #include "eal_memcfg.h" 16 : : 17 : : /* The frequency of the RDTSC timer resolution */ 18 : : static uint64_t eal_tsc_resolution_hz; 19 : : 20 : : /* Pointer to user delay function */ 21 : : void (*rte_delay_us)(unsigned int) = NULL; 22 : : 23 : : void 24 : 496582 : rte_delay_us_block(unsigned int us) 25 : : { 26 : : const uint64_t start = rte_get_timer_cycles(); 27 : 506838 : const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; 28 [ + + ]: 137181045 : while ((rte_get_timer_cycles() - start) < ticks) 29 : : rte_pause(); 30 : 463142 : } 31 : : 32 : : uint64_t 33 : 511104 : rte_get_tsc_hz(void) 34 : : { 35 : 511104 : return eal_tsc_resolution_hz; 36 : : } 37 : : 38 : : static uint64_t 39 : 0 : estimate_tsc_freq(void) 40 : : { 41 : : #define CYC_PER_10MHZ 1E7 42 : 0 : EAL_LOG(WARNING, "WARNING: TSC frequency estimated roughly" 43 : : " - clock timings may be less accurate."); 44 : : /* assume that the rte_delay_us_sleep() will sleep for 1 second */ 45 : : uint64_t start = rte_rdtsc(); 46 : 0 : rte_delay_us_sleep(US_PER_S); 47 : : /* Round up to 10Mhz. 1E7 ~ 10Mhz */ 48 [ # # ]: 0 : return RTE_ALIGN_MUL_NEAR(rte_rdtsc() - start, CYC_PER_10MHZ); 49 : : } 50 : : 51 : : void 52 : 179 : set_tsc_freq(void) 53 : : { 54 : 179 : struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; 55 : : uint64_t freq; 56 : : 57 [ + + ]: 179 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) { 58 : : /* 59 : : * Just use the primary process calculated TSC rate in any 60 : : * secondary process. It avoids any unnecessary overhead on 61 : : * systems where arch-specific frequency detection is not 62 : : * available. 63 : : */ 64 : 25 : eal_tsc_resolution_hz = mcfg->tsc_hz; 65 : 25 : return; 66 : : } 67 : : 68 : 154 : freq = get_tsc_freq_arch(); 69 : 154 : freq = get_tsc_freq(freq); 70 [ - + ]: 154 : if (!freq) 71 : 0 : freq = estimate_tsc_freq(); 72 : : 73 : 154 : EAL_LOG(DEBUG, "TSC frequency is ~%" PRIu64 " KHz", freq / 1000); 74 : 154 : eal_tsc_resolution_hz = freq; 75 : 154 : mcfg->tsc_hz = freq; 76 : : } 77 : : 78 : 253 : void rte_delay_us_callback_register(void (*userfunc)(unsigned int)) 79 : : { 80 : 253 : rte_delay_us = userfunc; 81 : 253 : } 82 : : 83 : 251 : RTE_INIT(rte_timer_init) 84 : : { 85 : : /* set rte_delay_us_block as a delay function */ 86 : 251 : rte_delay_us_callback_register(rte_delay_us_block); 87 : 251 : }