Getting extremely volatile results from get_tsc_hz(). Here's what I get from 10 successive calls:
freq=2660000000 freq=3220000000 freq=3740000000 freq=3870000000 freq=3830000000 freq=4060000000 freq=3370000000 freq=3820000000 freq=7370000000 freq=4970000000 Please see the last comment for the reason (and other comments inline). On 2020-05-06 15:01 GMT+0300 Fady Bader wrote: > Implemented the needed Windows eal timer functions. > > Signed-off-by: Fady Bader <f...@mellanox.com> > --- [snip] > diff --git a/lib/librte_eal/windows/eal_timer.c > b/lib/librte_eal/windows/eal_timer.c > new file mode 100644 > index 000000000..108f66b54 > --- /dev/null > +++ b/lib/librte_eal/windows/eal_timer.c > @@ -0,0 +1,96 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright 2020 Mellanox Technologies, Ltd > + */ > +#include <inttypes.h> > +#include <time.h> > + > +#include <rte_windows.h> > +#include <rte_common.h> > +#include <rte_log.h> > +#include <rte_cycles.h> > +#include <rte_eal.h> > +#include <rte_errno.h> #include "eal_private.h", without it: ../../../lib/librte_eal/windows/eal_timer.c: In function ‘rte_eal_timer_init’: ../../../lib/librte_eal/windows/eal_timer.c:108:2: warning: implicit declaration of function ‘set_tsc_freq’; did you mean ‘get_tsc_freq’? [-Wimplicit-function-declaration] 108 | set_tsc_freq(); > + > +#define US_PER_SEC 1E6 > +#define CYC_PER_10MHZ 1E7 > + > +/* The frequency of the RDTSC timer resolution */ > +static uint64_t eal_tsc_resolution_hz; > + At top level: ../../../lib/librte_eal/windows/eal_timer.c:20:17: warning: ‘eal_tsc_resolution_hz’ defined but not used [-Wunused-variable] 20 | static uint64_t eal_tsc_resolution_hz; Note: set_tsc_freq() already caches frequency you calculate here. > + due_time.QuadPart = -(us * 10); > + if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) { > + CloseHandle(timer); > + RTE_LOG_WIN32_ERR("SetWaitableTimer()"); RTE_LOG_WIN32_ERR() uses GetLastError(), the value of which may be overridden by a successful call to CloseHandle(). > + rte_errno = EINVAL; > + return; > + } > + /* start wait for timer for us microseconds */ > + WaitForSingleObject(timer, INFINITE); > + CloseHandle(timer); > +} > + > +uint64_t > +get_tsc_freq(void) > +{ > + LARGE_INTEGER t_start, t_end, elapsed_us; > + LARGE_INTEGER frequency; > + uint64_t tsc_hz; > + > + if (QueryPerformanceFrequency(&frequency) == 0) { > + RTE_LOG_WIN32_ERR("QueryPerformanceFrequency()"); > + return 0; > + } > + > + if (QueryPerformanceCounter(&t_start) != 0) { Per MSDN, QueryPerformanceFrequency() and QueryPerformanceCounter() always succeed on all supported Windows versions. > + uint64_t end, start = rte_get_tsc_cycles(); > + > + rte_delay_us(US_PER_SEC / 10); /* 1/10 second */ Did you mean rte_delay_us_sleep()? rte_delay_us() assumes TSC frequency is already available. With this fix, results become stable. -- Dmitry Kozlyuk