This patchset splits OS dependent EAL timer functions and implements them for windows. Depends-on: series-9374 ("Windows basic memory management") Fady Bader (2): timer: move from common to Unix directory timer: support EAL functions on Windows lib/librte_eal/common/eal_common_timer.c | 22 ----------- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/unix/eal_timer.c | 29 ++++++++++++++ lib/librte_eal/unix/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 67 ++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 8 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_timer.c create mode 100644 lib/librte_eal/windows/eal_timer.c -- 2.16.1.windows.4
Eal common timer doesn't compile under Windows. Compilation log: error LNK2019: unresolved external symbol nanosleep referenced in function rte_delay_us_sleep error LNK2019: unresolved external symbol get_tsc_freq referenced in function set_tsc_freq error LNK2019: unresolved external symbol sleep referenced in function set_tsc_freq The reason was that some functions called POSIX functions. The solution was to move POSIX dependent functions from common to Unix. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/eal_common_timer.c | 22 ---------------------- lib/librte_eal/unix/eal_timer.c | 29 +++++++++++++++++++++++++++++ lib/librte_eal/unix/meson.build | 1 + 3 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_timer.c diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c index fa9ee1b22..71e0bd035 100644 --- a/lib/librte_eal/common/eal_common_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -35,28 +35,6 @@ rte_delay_us_block(unsigned int us) rte_pause(); } -void -rte_delay_us_sleep(unsigned int us) -{ - struct timespec wait[2]; - int ind = 0; - - wait[0].tv_sec = 0; - if (us >= US_PER_S) { - wait[0].tv_sec = us / US_PER_S; - us -= wait[0].tv_sec * US_PER_S; - } - wait[0].tv_nsec = 1000 * us; - - while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { - /* - * Sleep was interrupted. Flip the index, so the 'remainder' - * will become the 'request' for a next call. - */ - ind = 1 - ind; - } -} - uint64_t rte_get_tsc_hz(void) { diff --git a/lib/librte_eal/unix/eal_timer.c b/lib/librte_eal/unix/eal_timer.c new file mode 100644 index 000000000..36189c346 --- /dev/null +++ b/lib/librte_eal/unix/eal_timer.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ +#include <time.h> + +#include <rte_cycles.h> + +void +rte_delay_us_sleep(unsigned int us) +{ + struct timespec wait[2]; + int ind = 0; + + wait[0].tv_sec = 0; + if (us >= US_PER_S) { + wait[0].tv_sec = us / US_PER_S; + us -= wait[0].tv_sec * US_PER_S; + } + wait[0].tv_nsec = 1000 * us; + + while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { + /* + * Sleep was interrupted. Flip the index, so the 'remainder' + * will become the 'request' for a next call. + */ + ind = 1 - ind; + } +} + diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build index 50c019a56..9da601658 100644 --- a/lib/librte_eal/unix/meson.build +++ b/lib/librte_eal/unix/meson.build @@ -4,4 +4,5 @@ sources += files( 'eal.c', 'eal_memory.c', + 'eal_timer.c', ) -- 2.16.1.windows.4
Implemented the needed Windows eal timer functions. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 67 +++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 5 files changed, 77 insertions(+) create mode 100644 lib/librte_eal/windows/eal_timer.c diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index 6dcdcc890..532330e6d 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -20,6 +20,7 @@ if is_windows 'eal_common_options.c', 'eal_common_tailqs.c', 'eal_common_thread.c', + 'eal_common_timer.c', 'malloc_elem.c', 'malloc_heap.c', 'rte_malloc.c', diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index 38f17f09c..32853fbac 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -400,6 +400,12 @@ rte_eal_init(int argc, char **argv) return -1; } + if (rte_eal_timer_init() < 0) { + rte_eal_init_alert("Cannot init TSC timer"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); RTE_LCORE_FOREACH_SLAVE(i) { diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c new file mode 100644 index 000000000..73eaff948 --- /dev/null +++ b/lib/librte_eal/windows/eal_timer.c @@ -0,0 +1,67 @@ +/* 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> + +/* The frequency of the RDTSC timer resolution */ +static uint64_t eal_tsc_resolution_hz; + +void +rte_delay_us_sleep(unsigned int us) +{ + LONGLONG ns = us * 1000; + HANDLE timer; + LARGE_INTEGER liDueTime; + /* create waitable timer */ + timer = CreateWaitableTimer(NULL, TRUE, NULL); + if(!timer){ + /* didnt find any better errno val */ + rte_errno = EINVAL; + return; + } + + /* set us microseconds time for timer */ + liDueTime.QuadPart = -ns; + if(!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE)){ + CloseHandle(timer); + /* didnt find any better errno val */ + rte_errno = EFAULT; + return; + } + /* start wait for timer for us microseconds */ + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); +} + +uint64_t +get_tsc_freq(void) +{ + uint64_t tsc_freq; + LARGE_INTEGER Frequency; + + QueryPerformanceFrequency(&Frequency); + /* + QueryPerformanceFrequency output is in khz. + Mulitply by 1K to obtain the true frequency of the CPU (khz -> hz) + */ + tsc_freq = ((uint64_t)Frequency.QuadPart * 1000); + + return tsc_freq; +} + + +int +rte_eal_timer_init(void) +{ + set_tsc_freq(); + return 0; +} + diff --git a/lib/librte_eal/windows/include/rte_os.h b/lib/librte_eal/windows/include/rte_os.h index 62805a307..951a14d72 100644 --- a/lib/librte_eal/windows/include/rte_os.h +++ b/lib/librte_eal/windows/include/rte_os.h @@ -24,6 +24,8 @@ extern "C" { #define PATH_MAX _MAX_PATH #endif +#define sleep(x) Sleep(1000 * x) + #define strerror_r(a, b, c) strerror_s(b, c, a) /* strdup is deprecated in Microsoft libc and _strdup is preferred */ diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build index 0bd56cd8f..769cde797 100644 --- a/lib/librte_eal/windows/meson.build +++ b/lib/librte_eal/windows/meson.build @@ -12,6 +12,7 @@ sources += files( 'eal_memory.c', 'eal_mp.c', 'eal_thread.c', + 'eal_timer.c', 'getopt.c', ) -- 2.16.1.windows.4
On 2020-04-23 17:43 GMT+0300 Fady Bader wrote: [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..73eaff948 > --- /dev/null > +++ b/lib/librte_eal/windows/eal_timer.c > @@ -0,0 +1,67 @@ > +/* 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> > + > +/* The frequency of the RDTSC timer resolution */ > +static uint64_t eal_tsc_resolution_hz; > + > +void > +rte_delay_us_sleep(unsigned int us) > +{ > + LONGLONG ns = us * 1000; > + HANDLE timer; > + LARGE_INTEGER liDueTime; Shouldn't Windows code follow DPDK naming conventions? > + /* create waitable timer */ > + timer = CreateWaitableTimer(NULL, TRUE, NULL); > + if(!timer){ Missing spaces. There are more styling issues below that could be detected by running ./devtools/checkpatches.sh. > + /* didnt find any better errno val */ > + rte_errno = EINVAL; > + return; ENOMEM probably indicates lack of resources better. EINVAL usually implies wrong arguments to the function. You can also use RTE_WIN32_LOG_ERR() here to log exact error code on debug level. > + } > + > + /* set us microseconds time for timer */ > + liDueTime.QuadPart = -ns; Timeout is neither in microseconds, nor in nanoseconds, it's in 100-nanosecond intervals. > + if(!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE)){ > + CloseHandle(timer); > + /* didnt find any better errno val */ > + rte_errno = EFAULT; And here, EINVAL is probably better, because result depends on function argument and this probably will be the most frequent source of errors. > + return; > + } > + /* start wait for timer for us microseconds */ > + WaitForSingleObject(timer, INFINITE); > + CloseHandle(timer); > +} [snip] > diff --git a/lib/librte_eal/windows/include/rte_os.h b/lib/librte_eal/windows/include/rte_os.h > index 62805a307..951a14d72 100644 > --- a/lib/librte_eal/windows/include/rte_os.h > +++ b/lib/librte_eal/windows/include/rte_os.h > @@ -24,6 +24,8 @@ extern "C" { > #define PATH_MAX _MAX_PATH > #endif > > +#define sleep(x) Sleep(1000 * x) It's better to enclose "x" in parentheses or to use inline function. -- Dmitry Kozlyuk
On 2020-04-23 17:43 GMT+0300 Fady Bader wrote:
> +uint64_t
> +get_tsc_freq(void)
> +{
> + uint64_t tsc_freq;
> + LARGE_INTEGER Frequency;
> +
> + QueryPerformanceFrequency(&Frequency);
> + /*
> + QueryPerformanceFrequency output is in khz.
> + Mulitply by 1K to obtain the true frequency of the CPU (khz -> hz)
> + */
> + tsc_freq = ((uint64_t)Frequency.QuadPart * 1000);
> +
> + return tsc_freq;
> +}
QueryPerformanceFrequency() output is in Hz of TSC, not CPU clock. To get
real time interval from TSC difference, we divide that difference to TSC
frequency with no additional 1000 multiplier.
P.S. Fixed my address in Cc.
--
Dmitry Kozlyuk
This patchset splits OS dependent EAL timer functions and implements them for windows. v2: * fixing styles and correctness errors. v3: * fixing correctness, get_tsc_freq was reimplemented. v4: * rebasing to the new version of "Windows basic memory management" series. * fixing styles and correctness errors. v5: * breaking the dependency on "Windows basic memory management" series. * fixing correctness errors and warnings. v6: * fixing styles and correctness errors. v7: * fixing make errors. v8: * fixing error handling issue. * removed unneded headers. v9: * rebasing to current master. * fixing correctness issue. Fady Bader (2): timer: move from common to Unix directory timer: support EAL functions on Windows lib/librte_eal/common/eal_common_timer.c | 22 -------- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/unix/eal_unix_timer.c | 29 ++++++++++ lib/librte_eal/unix/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 91 ++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 10 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_unix_timer.c create mode 100644 lib/librte_eal/windows/eal_timer.c -- 2.16.1.windows.4
Eal common timer doesn't compile under Windows. Compilation log: error LNK2019: unresolved external symbol nanosleep referenced in function rte_delay_us_sleep error LNK2019: unresolved external symbol get_tsc_freq referenced in function set_tsc_freq error LNK2019: unresolved external symbol sleep referenced in function set_tsc_freq The reason was that some functions called POSIX functions. The solution was to move POSIX dependent functions from common to Unix. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/eal_common_timer.c | 22 ---------------------- lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/unix/eal_unix_timer.c | 29 +++++++++++++++++++++++++++++ lib/librte_eal/unix/meson.build | 1 + 5 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_unix_timer.c diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c index fa9ee1b224..71e0bd035a 100644 --- a/lib/librte_eal/common/eal_common_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -35,28 +35,6 @@ rte_delay_us_block(unsigned int us) rte_pause(); } -void -rte_delay_us_sleep(unsigned int us) -{ - struct timespec wait[2]; - int ind = 0; - - wait[0].tv_sec = 0; - if (us >= US_PER_S) { - wait[0].tv_sec = us / US_PER_S; - us -= wait[0].tv_sec * US_PER_S; - } - wait[0].tv_nsec = 1000 * us; - - while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { - /* - * Sleep was interrupted. Flip the index, so the 'remainder' - * will become the 'request' for a next call. - */ - ind = 1 - ind; - } -} - uint64_t rte_get_tsc_hz(void) { diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index 2374ba0b7d..d18c00eeae 100644 --- a/lib/librte_eal/freebsd/Makefile +++ b/lib/librte_eal/freebsd/Makefile @@ -78,6 +78,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_reciprocal.c # from unix dir SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_file.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_unix_memory.c +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_unix_timer.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_cpuflags.c diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile index 07ce643bae..5d97073ed2 100644 --- a/lib/librte_eal/linux/Makefile +++ b/lib/librte_eal/linux/Makefile @@ -86,6 +86,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_reciprocal.c # from unix dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_file.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_unix_memory.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_unix_timer.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_cpuflags.c diff --git a/lib/librte_eal/unix/eal_unix_timer.c b/lib/librte_eal/unix/eal_unix_timer.c new file mode 100644 index 0000000000..cc50159104 --- /dev/null +++ b/lib/librte_eal/unix/eal_unix_timer.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ + +#include <time.h> + +#include <rte_cycles.h> + +void +rte_delay_us_sleep(unsigned int us) +{ + struct timespec wait[2]; + int ind = 0; + + wait[0].tv_sec = 0; + if (us >= US_PER_S) { + wait[0].tv_sec = us / US_PER_S; + us -= wait[0].tv_sec * US_PER_S; + } + wait[0].tv_nsec = 1000 * us; + + while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { + /* + * Sleep was interrupted. Flip the index, so the 'remainder' + * will become the 'request' for a next call. + */ + ind = 1 - ind; + } +} diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build index e733910a1a..d3af6b6fe2 100644 --- a/lib/librte_eal/unix/meson.build +++ b/lib/librte_eal/unix/meson.build @@ -4,4 +4,5 @@ sources += files( 'eal_file.c', 'eal_unix_memory.c', + 'eal_unix_timer.c', ) -- 2.16.1.windows.4
Implemented the needed Windows eal timer functions. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 91 +++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 5 files changed, 101 insertions(+) create mode 100644 lib/librte_eal/windows/eal_timer.c diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index 3108442697..4bdf77922f 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -26,6 +26,7 @@ if is_windows 'malloc_elem.c', 'malloc_heap.c', 'rte_malloc.c', + 'eal_common_timer.c', ) subdir_done() endif diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index 427a5557fa..b6bffd3d92 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -354,6 +354,12 @@ rte_eal_init(int argc, char **argv) return -1; } + if (rte_eal_timer_init() < 0) { + rte_eal_init_alert("Cannot init TSC timer"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); RTE_LCORE_FOREACH_SLAVE(i) { diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c new file mode 100644 index 0000000000..59099e8942 --- /dev/null +++ b/lib/librte_eal/windows/eal_timer.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ +#include <inttypes.h> + +#include <rte_windows.h> +#include <rte_common.h> +#include <rte_cycles.h> +#include <rte_eal.h> +#include <rte_errno.h> +#include "eal_private.h" + +#define US_PER_SEC 1E6 +#define CYC_PER_10MHZ 1E7 + +void +rte_delay_us_sleep(unsigned int us) +{ + HANDLE timer; + LARGE_INTEGER due_time; + + /* create waitable timer */ + timer = CreateWaitableTimer(NULL, TRUE, NULL); + if (!timer) { + RTE_LOG_WIN32_ERR("CreateWaitableTimer()"); + rte_errno = ENOMEM; + return; + } + + /* + * due_time's uom is 100 ns, multiply by 10 to convert to microseconds + * set us microseconds time for timer + */ + due_time.QuadPart = -((int64_t)us * 10); + if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) { + RTE_LOG_WIN32_ERR("SetWaitableTimer()"); + rte_errno = EINVAL; + goto end; + } + /* start wait for timer for us microseconds */ + if (WaitForSingleObject(timer, INFINITE) == WAIT_FAILED) { + RTE_LOG_WIN32_ERR("WaitForSingleObject()"); + rte_errno = EINVAL; + } + +end: + CloseHandle(timer); +} + +uint64_t +get_tsc_freq(void) +{ + LARGE_INTEGER t_start, t_end, elapsed_us; + LARGE_INTEGER frequency; + uint64_t tsc_hz; + uint64_t end, start = rte_get_tsc_cycles(); + + QueryPerformanceCounter(&t_start); + QueryPerformanceFrequency(&frequency); + + rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ + + if (rte_errno != 0) + return 0; + + QueryPerformanceCounter(&t_end); + end = rte_get_tsc_cycles(); + + elapsed_us.QuadPart = t_end.QuadPart - t_start.QuadPart; + + /* + * To guard against loss-of-precision, convert to microseconds + * *before* dividing by ticks-per-second. + */ + elapsed_us.QuadPart *= US_PER_SEC; + elapsed_us.QuadPart /= frequency.QuadPart; + + double secs = ((double)elapsed_us.QuadPart)/US_PER_SEC; + tsc_hz = (uint64_t)((end - start)/secs); + + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ + return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ); +} + + +int +rte_eal_timer_init(void) +{ + set_tsc_freq(); + return 0; +} diff --git a/lib/librte_eal/windows/include/rte_os.h b/lib/librte_eal/windows/include/rte_os.h index cb10d6494f..569ed92d51 100644 --- a/lib/librte_eal/windows/include/rte_os.h +++ b/lib/librte_eal/windows/include/rte_os.h @@ -25,6 +25,8 @@ extern "C" { #define PATH_MAX _MAX_PATH #endif +#define sleep(x) Sleep(1000 * (x)) + #define strerror_r(a, b, c) strerror_s(b, c, a) /* strdup is deprecated in Microsoft libc and _strdup is preferred */ diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build index ded5a2b808..08c888e018 100644 --- a/lib/librte_eal/windows/meson.build +++ b/lib/librte_eal/windows/meson.build @@ -14,6 +14,7 @@ sources += files( 'eal_memory.c', 'eal_mp.c', 'eal_thread.c', + 'eal_timer.c', 'fnmatch.c', 'getopt.c', ) -- 2.16.1.windows.4
On 6/17/2020 2:39 AM, Fady Bader wrote: > Implemented the needed Windows eal timer functions. > > Signed-off-by: Fady Bader <fady@mellanox.com> > --- > lib/librte_eal/common/meson.build | 1 + > lib/librte_eal/windows/eal.c | 6 +++ > lib/librte_eal/windows/eal_timer.c | 91 +++++++++++++++++++++++++++++++++ > lib/librte_eal/windows/include/rte_os.h | 2 + > lib/librte_eal/windows/meson.build | 1 + > 5 files changed, 101 insertions(+) > create mode 100644 lib/librte_eal/windows/eal_timer.c > > diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build > index 3108442697..4bdf77922f 100644 > --- a/lib/librte_eal/common/meson.build > +++ b/lib/librte_eal/common/meson.build > @@ -26,6 +26,7 @@ if is_windows > 'malloc_elem.c', > 'malloc_heap.c', > 'rte_malloc.c', > + 'eal_common_timer.c', > ) > subdir_done() > endif > diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c > index 427a5557fa..b6bffd3d92 100644 > --- a/lib/librte_eal/windows/eal.c > +++ b/lib/librte_eal/windows/eal.c > @@ -354,6 +354,12 @@ rte_eal_init(int argc, char **argv) > return -1; > } > > + if (rte_eal_timer_init() < 0) { > + rte_eal_init_alert("Cannot init TSC timer"); > + rte_errno = EFAULT; > + return -1; > + } > + > eal_thread_init_master(rte_config.master_lcore); > > RTE_LCORE_FOREACH_SLAVE(i) { > diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c > new file mode 100644 > index 0000000000..59099e8942 > --- /dev/null > +++ b/lib/librte_eal/windows/eal_timer.c > @@ -0,0 +1,91 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright 2020 Mellanox Technologies, Ltd > + */ > +#include <inttypes.h> > + > +#include <rte_windows.h> > +#include <rte_common.h> > +#include <rte_cycles.h> > +#include <rte_eal.h> > +#include <rte_errno.h> > +#include "eal_private.h" > + > +#define US_PER_SEC 1E6 > +#define CYC_PER_10MHZ 1E7 > + > +void > +rte_delay_us_sleep(unsigned int us) > +{ > + HANDLE timer; > + LARGE_INTEGER due_time; > + > + /* create waitable timer */ > + timer = CreateWaitableTimer(NULL, TRUE, NULL); > + if (!timer) { > + RTE_LOG_WIN32_ERR("CreateWaitableTimer()"); > + rte_errno = ENOMEM; > + return; > + } > + > + /* > + * due_time's uom is 100 ns, multiply by 10 to convert to microseconds > + * set us microseconds time for timer > + */ > + due_time.QuadPart = -((int64_t)us * 10); > + if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) { > + RTE_LOG_WIN32_ERR("SetWaitableTimer()"); > + rte_errno = EINVAL; > + goto end; > + } > + /* start wait for timer for us microseconds */ > + if (WaitForSingleObject(timer, INFINITE) == WAIT_FAILED) { > + RTE_LOG_WIN32_ERR("WaitForSingleObject()"); > + rte_errno = EINVAL; > + } > + > +end: > + CloseHandle(timer); > +} > + > +uint64_t > +get_tsc_freq(void) > +{ > + LARGE_INTEGER t_start, t_end, elapsed_us; > + LARGE_INTEGER frequency; > + uint64_t tsc_hz; > + uint64_t end, start = rte_get_tsc_cycles(); I think a better implementation may be: uint64_t start, end; QueryPerformanceFrequency(&frequency); start = rte_get_tsc_cycles(); QueryPerformanceCounter(&t_start); rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ ..... > + > + QueryPerformanceCounter(&t_start); > + QueryPerformanceFrequency(&frequency); > + > + rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ > + > + if (rte_errno != 0) > + return 0; > + > + QueryPerformanceCounter(&t_end); > + end = rte_get_tsc_cycles(); > + > + elapsed_us.QuadPart = t_end.QuadPart - t_start.QuadPart; > + > + /* > + * To guard against loss-of-precision, convert to microseconds > + * *before* dividing by ticks-per-second. > + */ > + elapsed_us.QuadPart *= US_PER_SEC; > + elapsed_us.QuadPart /= frequency.QuadPart; > + > + double secs = ((double)elapsed_us.QuadPart)/US_PER_SEC; > + tsc_hz = (uint64_t)((end - start)/secs); > + > + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ > + return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ); > +} [Snip] ranjit m.
This patchset splits OS dependent EAL timer functions and implements them for windows. v2: * fixing styles and correctness errors. v3: * fixing correctness, get_tsc_freq was reimplemented. v4: * rebasing to the new version of "Windows basic memory management" series. * fixing styles and correctness errors. v5: * breaking the dependency on "Windows basic memory management" series. * fixing correctness errors and warnings. v6: * fixing styles and correctness errors. v7: * fixing make errors. v8: * fixing error handling issue. * removed unneded headers. v9: * rebasing to current master. * fixing correctness issue. v10: * fixing correctness issue. Fady Bader (2): timer: move from common to Unix directory timer: support EAL functions on Windows lib/librte_eal/common/eal_common_timer.c | 22 -------- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/unix/eal_unix_timer.c | 29 ++++++++++ lib/librte_eal/unix/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 93 ++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 10 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_unix_timer.c create mode 100644 lib/librte_eal/windows/eal_timer.c -- 2.16.1.windows.4
Eal common timer doesn't compile under Windows. Compilation log: error LNK2019: unresolved external symbol nanosleep referenced in function rte_delay_us_sleep error LNK2019: unresolved external symbol get_tsc_freq referenced in function set_tsc_freq error LNK2019: unresolved external symbol sleep referenced in function set_tsc_freq The reason was that some functions called POSIX functions. The solution was to move POSIX dependent functions from common to Unix. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/eal_common_timer.c | 22 ---------------------- lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/unix/eal_unix_timer.c | 29 +++++++++++++++++++++++++++++ lib/librte_eal/unix/meson.build | 1 + 5 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 lib/librte_eal/unix/eal_unix_timer.c diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c index fa9ee1b224..71e0bd035a 100644 --- a/lib/librte_eal/common/eal_common_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -35,28 +35,6 @@ rte_delay_us_block(unsigned int us) rte_pause(); } -void -rte_delay_us_sleep(unsigned int us) -{ - struct timespec wait[2]; - int ind = 0; - - wait[0].tv_sec = 0; - if (us >= US_PER_S) { - wait[0].tv_sec = us / US_PER_S; - us -= wait[0].tv_sec * US_PER_S; - } - wait[0].tv_nsec = 1000 * us; - - while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { - /* - * Sleep was interrupted. Flip the index, so the 'remainder' - * will become the 'request' for a next call. - */ - ind = 1 - ind; - } -} - uint64_t rte_get_tsc_hz(void) { diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index 2374ba0b7d..d18c00eeae 100644 --- a/lib/librte_eal/freebsd/Makefile +++ b/lib/librte_eal/freebsd/Makefile @@ -78,6 +78,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_reciprocal.c # from unix dir SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_file.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_unix_memory.c +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_unix_timer.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_cpuflags.c diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile index 07ce643bae..5d97073ed2 100644 --- a/lib/librte_eal/linux/Makefile +++ b/lib/librte_eal/linux/Makefile @@ -86,6 +86,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_reciprocal.c # from unix dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_file.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_unix_memory.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_unix_timer.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_cpuflags.c diff --git a/lib/librte_eal/unix/eal_unix_timer.c b/lib/librte_eal/unix/eal_unix_timer.c new file mode 100644 index 0000000000..cc50159104 --- /dev/null +++ b/lib/librte_eal/unix/eal_unix_timer.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ + +#include <time.h> + +#include <rte_cycles.h> + +void +rte_delay_us_sleep(unsigned int us) +{ + struct timespec wait[2]; + int ind = 0; + + wait[0].tv_sec = 0; + if (us >= US_PER_S) { + wait[0].tv_sec = us / US_PER_S; + us -= wait[0].tv_sec * US_PER_S; + } + wait[0].tv_nsec = 1000 * us; + + while (nanosleep(&wait[ind], &wait[1 - ind]) && errno == EINTR) { + /* + * Sleep was interrupted. Flip the index, so the 'remainder' + * will become the 'request' for a next call. + */ + ind = 1 - ind; + } +} diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build index e733910a1a..d3af6b6fe2 100644 --- a/lib/librte_eal/unix/meson.build +++ b/lib/librte_eal/unix/meson.build @@ -4,4 +4,5 @@ sources += files( 'eal_file.c', 'eal_unix_memory.c', + 'eal_unix_timer.c', ) -- 2.16.1.windows.4
Implemented the needed Windows eal timer functions. Signed-off-by: Fady Bader <fady@mellanox.com> --- lib/librte_eal/common/meson.build | 1 + lib/librte_eal/windows/eal.c | 6 +++ lib/librte_eal/windows/eal_timer.c | 93 +++++++++++++++++++++++++++++++++ lib/librte_eal/windows/include/rte_os.h | 2 + lib/librte_eal/windows/meson.build | 1 + 5 files changed, 103 insertions(+) create mode 100644 lib/librte_eal/windows/eal_timer.c diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index 3108442697..4bdf77922f 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -26,6 +26,7 @@ if is_windows 'malloc_elem.c', 'malloc_heap.c', 'rte_malloc.c', + 'eal_common_timer.c', ) subdir_done() endif diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index 427a5557fa..b6bffd3d92 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -354,6 +354,12 @@ rte_eal_init(int argc, char **argv) return -1; } + if (rte_eal_timer_init() < 0) { + rte_eal_init_alert("Cannot init TSC timer"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); RTE_LCORE_FOREACH_SLAVE(i) { diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c new file mode 100644 index 0000000000..1f0cae631c --- /dev/null +++ b/lib/librte_eal/windows/eal_timer.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ +#include <inttypes.h> + +#include <rte_windows.h> +#include <rte_common.h> +#include <rte_cycles.h> +#include <rte_eal.h> +#include <rte_errno.h> +#include "eal_private.h" + +#define US_PER_SEC 1E6 +#define CYC_PER_10MHZ 1E7 + +void +rte_delay_us_sleep(unsigned int us) +{ + HANDLE timer; + LARGE_INTEGER due_time; + + /* create waitable timer */ + timer = CreateWaitableTimer(NULL, TRUE, NULL); + if (!timer) { + RTE_LOG_WIN32_ERR("CreateWaitableTimer()"); + rte_errno = ENOMEM; + return; + } + + /* + * due_time's uom is 100 ns, multiply by 10 to convert to microseconds + * set us microseconds time for timer + */ + due_time.QuadPart = -((int64_t)us * 10); + if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) { + RTE_LOG_WIN32_ERR("SetWaitableTimer()"); + rte_errno = EINVAL; + goto end; + } + /* start wait for timer for us microseconds */ + if (WaitForSingleObject(timer, INFINITE) == WAIT_FAILED) { + RTE_LOG_WIN32_ERR("WaitForSingleObject()"); + rte_errno = EINVAL; + } + +end: + CloseHandle(timer); +} + +uint64_t +get_tsc_freq(void) +{ + LARGE_INTEGER t_start, t_end, elapsed_us; + LARGE_INTEGER frequency; + uint64_t tsc_hz; + uint64_t end, start; + + QueryPerformanceFrequency(&frequency); + + QueryPerformanceCounter(&t_start); + start = rte_get_tsc_cycles(); + + rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ + + if (rte_errno != 0) + return 0; + + QueryPerformanceCounter(&t_end); + end = rte_get_tsc_cycles(); + + elapsed_us.QuadPart = t_end.QuadPart - t_start.QuadPart; + + /* + * To guard against loss-of-precision, convert to microseconds + * *before* dividing by ticks-per-second. + */ + elapsed_us.QuadPart *= US_PER_SEC; + elapsed_us.QuadPart /= frequency.QuadPart; + + double secs = ((double)elapsed_us.QuadPart)/US_PER_SEC; + tsc_hz = (uint64_t)((end - start)/secs); + + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ + return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ); +} + + +int +rte_eal_timer_init(void) +{ + set_tsc_freq(); + return 0; +} diff --git a/lib/librte_eal/windows/include/rte_os.h b/lib/librte_eal/windows/include/rte_os.h index cb10d6494f..569ed92d51 100644 --- a/lib/librte_eal/windows/include/rte_os.h +++ b/lib/librte_eal/windows/include/rte_os.h @@ -25,6 +25,8 @@ extern "C" { #define PATH_MAX _MAX_PATH #endif +#define sleep(x) Sleep(1000 * (x)) + #define strerror_r(a, b, c) strerror_s(b, c, a) /* strdup is deprecated in Microsoft libc and _strdup is preferred */ diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build index ded5a2b808..08c888e018 100644 --- a/lib/librte_eal/windows/meson.build +++ b/lib/librte_eal/windows/meson.build @@ -14,6 +14,7 @@ sources += files( 'eal_memory.c', 'eal_mp.c', 'eal_thread.c', + 'eal_timer.c', 'fnmatch.c', 'getopt.c', ) -- 2.16.1.windows.4
> -----Original Message----- > From: Ranjit Menon <ranjit.menon@intel.com> > Sent: Thursday, June 18, 2020 1:16 AM > To: Fady Bader <fady@mellanox.com>; dev@dpdk.org > Cc: Thomas Monjalon <thomas@monjalon.net>; Tasnim Bashar > <tbashar@mellanox.com>; Tal Shnaiderman <talshn@mellanox.com>; Yohad Tor > <yohadt@mellanox.com>; dmitry.kozliuk@gmail.com; > harini.ramakrishnan@microsoft.com; ocardona@microsoft.com; > pallavi.kadam@intel.com > Subject: Re: [PATCH v9 2/2] timer: support EAL functions on Windows > > > On 6/17/2020 2:39 AM, Fady Bader wrote: > > Implemented the needed Windows eal timer functions. > > > > Signed-off-by: Fady Bader <fady@mellanox.com> > > --- > > lib/librte_eal/common/meson.build | 1 + > > lib/librte_eal/windows/eal.c | 6 +++ > > lib/librte_eal/windows/eal_timer.c | 91 > +++++++++++++++++++++++++++++++++ > > lib/librte_eal/windows/include/rte_os.h | 2 + > > lib/librte_eal/windows/meson.build | 1 + > > 5 files changed, 101 insertions(+) > > create mode 100644 lib/librte_eal/windows/eal_timer.c > > > > diff --git a/lib/librte_eal/common/meson.build > > b/lib/librte_eal/common/meson.build > > index 3108442697..4bdf77922f 100644 > > --- a/lib/librte_eal/common/meson.build > > +++ b/lib/librte_eal/common/meson.build > > @@ -26,6 +26,7 @@ if is_windows > > 'malloc_elem.c', > > 'malloc_heap.c', > > 'rte_malloc.c', > > + 'eal_common_timer.c', > > ) > > subdir_done() > > endif > > diff --git a/lib/librte_eal/windows/eal.c > > b/lib/librte_eal/windows/eal.c index 427a5557fa..b6bffd3d92 100644 > > --- a/lib/librte_eal/windows/eal.c > > +++ b/lib/librte_eal/windows/eal.c > > @@ -354,6 +354,12 @@ rte_eal_init(int argc, char **argv) > > return -1; > > } > > > > + if (rte_eal_timer_init() < 0) { > > + rte_eal_init_alert("Cannot init TSC timer"); > > + rte_errno = EFAULT; > > + return -1; > > + } > > + > > eal_thread_init_master(rte_config.master_lcore); > > > > RTE_LCORE_FOREACH_SLAVE(i) { > > diff --git a/lib/librte_eal/windows/eal_timer.c > > b/lib/librte_eal/windows/eal_timer.c > > new file mode 100644 > > index 0000000000..59099e8942 > > --- /dev/null > > +++ b/lib/librte_eal/windows/eal_timer.c > > @@ -0,0 +1,91 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright 2020 Mellanox Technologies, Ltd */ #include > > +<inttypes.h> > > + > > +#include <rte_windows.h> > > +#include <rte_common.h> > > +#include <rte_cycles.h> > > +#include <rte_eal.h> > > +#include <rte_errno.h> > > +#include "eal_private.h" > > + > > +#define US_PER_SEC 1E6 > > +#define CYC_PER_10MHZ 1E7 > > + > > +void > > +rte_delay_us_sleep(unsigned int us) > > +{ > > + HANDLE timer; > > + LARGE_INTEGER due_time; > > + > > + /* create waitable timer */ > > + timer = CreateWaitableTimer(NULL, TRUE, NULL); > > + if (!timer) { > > + RTE_LOG_WIN32_ERR("CreateWaitableTimer()"); > > + rte_errno = ENOMEM; > > + return; > > + } > > + > > + /* > > + * due_time's uom is 100 ns, multiply by 10 to convert to microseconds > > + * set us microseconds time for timer > > + */ > > + due_time.QuadPart = -((int64_t)us * 10); > > + if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, FALSE)) { > > + RTE_LOG_WIN32_ERR("SetWaitableTimer()"); > > + rte_errno = EINVAL; > > + goto end; > > + } > > + /* start wait for timer for us microseconds */ > > + if (WaitForSingleObject(timer, INFINITE) == WAIT_FAILED) { > > + RTE_LOG_WIN32_ERR("WaitForSingleObject()"); > > + rte_errno = EINVAL; > > + } > > + > > +end: > > + CloseHandle(timer); > > +} > > + > > +uint64_t > > +get_tsc_freq(void) > > +{ > > + LARGE_INTEGER t_start, t_end, elapsed_us; > > + LARGE_INTEGER frequency; > > + uint64_t tsc_hz; > > + uint64_t end, start = rte_get_tsc_cycles(); > > I think a better implementation may be: > > uint64_t start, end; > > QueryPerformanceFrequency(&frequency); > > start = rte_get_tsc_cycles(); > QueryPerformanceCounter(&t_start); > > rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ > > ..... > You are correct. I've sent another patch. Thanks, Fady > > + > > + QueryPerformanceCounter(&t_start); > > + QueryPerformanceFrequency(&frequency); > > + > > + rte_delay_us_sleep(US_PER_SEC / 10); /* 1/10 second */ > > + > > + if (rte_errno != 0) > > + return 0; > > + > > + QueryPerformanceCounter(&t_end); > > + end = rte_get_tsc_cycles(); > > + > > + elapsed_us.QuadPart = t_end.QuadPart - t_start.QuadPart; > > + > > + /* > > + * To guard against loss-of-precision, convert to microseconds > > + * *before* dividing by ticks-per-second. > > + */ > > + elapsed_us.QuadPart *= US_PER_SEC; > > + elapsed_us.QuadPart /= frequency.QuadPart; > > + > > + double secs = ((double)elapsed_us.QuadPart)/US_PER_SEC; > > + tsc_hz = (uint64_t)((end - start)/secs); > > + > > + /* Round up to 10Mhz. 1E7 ~ 10Mhz */ > > + return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ); } > > [Snip] > > ranjit m.
On 6/17/2020 11:55 PM, Fady Bader wrote:
> This patchset splits OS dependent EAL timer functions and implements them for windows.
>
> v2:
> * fixing styles and correctness errors.
> v3:
> * fixing correctness, get_tsc_freq was reimplemented.
> v4:
> * rebasing to the new version of "Windows basic memory management" series.
> * fixing styles and correctness errors.
> v5:
> * breaking the dependency on "Windows basic memory management" series.
> * fixing correctness errors and warnings.
> v6:
> * fixing styles and correctness errors.
> v7:
> * fixing make errors.
> v8:
> * fixing error handling issue.
> * removed unneded headers.
> v9:
> * rebasing to current master.
> * fixing correctness issue.
> v10:
> * fixing correctness issue.
>
> Fady Bader (2):
> timer: move from common to Unix directory
> timer: support EAL functions on Windows
>
> lib/librte_eal/common/eal_common_timer.c | 22 --------
> lib/librte_eal/common/meson.build | 1 +
> lib/librte_eal/freebsd/Makefile | 1 +
> lib/librte_eal/linux/Makefile | 1 +
> lib/librte_eal/unix/eal_unix_timer.c | 29 ++++++++++
> lib/librte_eal/unix/meson.build | 1 +
> lib/librte_eal/windows/eal.c | 6 +++
> lib/librte_eal/windows/eal_timer.c | 93 ++++++++++++++++++++++++++++++++
> lib/librte_eal/windows/include/rte_os.h | 2 +
> lib/librte_eal/windows/meson.build | 1 +
> 10 files changed, 135 insertions(+), 22 deletions(-)
> create mode 100644 lib/librte_eal/unix/eal_unix_timer.c
> create mode 100644 lib/librte_eal/windows/eal_timer.c
Acked-by: Ranjit Menon <ranjit.menon@intel.com>
18/06/2020 21:32, Ranjit Menon:
> On 6/17/2020 11:55 PM, Fady Bader wrote:
> > This patchset splits OS dependent EAL timer functions and implements them for windows.
> >
> > v2:
> > * fixing styles and correctness errors.
> > v3:
> > * fixing correctness, get_tsc_freq was reimplemented.
> > v4:
> > * rebasing to the new version of "Windows basic memory management" series.
> > * fixing styles and correctness errors.
> > v5:
> > * breaking the dependency on "Windows basic memory management" series.
> > * fixing correctness errors and warnings.
> > v6:
> > * fixing styles and correctness errors.
> > v7:
> > * fixing make errors.
> > v8:
> > * fixing error handling issue.
> > * removed unneded headers.
> > v9:
> > * rebasing to current master.
> > * fixing correctness issue.
> > v10:
> > * fixing correctness issue.
> >
> > Fady Bader (2):
> > timer: move from common to Unix directory
> > timer: support EAL functions on Windows
> >
> Acked-by: Ranjit Menon <ranjit.menon@intel.com>
Applied, thanks