From 796744869669842bd5405a71de8ba60b1556fc24 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Mon, 25 May 2020 15:20:55 +0200 Subject: [PATCH] win, util: rearrange uv_hrtime Rearrange math operations in uv_hrtime. This is a workaround for a probable compiler bug in VS2019. Fixes: https://github.com/libuv/libuv/issues/1633 PR-URL: https://github.com/libuv/libuv/pull/2866 Reviewed-By: Anna Henningsen Reviewed-By: Ben Noordhuis --- src/win/internal.h | 2 +- src/win/util.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/win/internal.h b/src/win/internal.h index 058ddb8e..b096255e 100644 --- a/src/win/internal.h +++ b/src/win/internal.h @@ -266,7 +266,7 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); */ void uv__util_init(void); -uint64_t uv__hrtime(double scale); +uint64_t uv__hrtime(unsigned int scale); __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); int uv__getpwuid_r(uv_passwd_t* pwd); int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); diff --git a/src/win/util.c b/src/win/util.c index 9e1e7f73..c63cdde3 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -67,8 +67,8 @@ extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength); static char *process_title; static CRITICAL_SECTION process_title_lock; -/* Interval (in seconds) of the high-resolution clock. */ -static double hrtime_interval_ = 0; +/* Frequency of the high-resolution clock. */ +static uint64_t hrtime_frequency_ = 0; /* @@ -84,9 +84,9 @@ void uv__util_init(void) { * and precompute its reciprocal. */ if (QueryPerformanceFrequency(&perf_frequency)) { - hrtime_interval_ = 1.0 / perf_frequency.QuadPart; + hrtime_frequency_ = perf_frequency.QuadPart; } else { - hrtime_interval_= 0; + uv_fatal_error(GetLastError(), "QueryPerformanceFrequency"); } } @@ -490,23 +490,23 @@ uint64_t uv_hrtime(void) { return uv__hrtime(UV__NANOSEC); } -uint64_t uv__hrtime(double scale) { +uint64_t uv__hrtime(unsigned int scale) { LARGE_INTEGER counter; - /* If the performance interval is zero, there's no support. */ - if (hrtime_interval_ == 0) { - return 0; - } - + assert(hrtime_frequency_ != 0); + assert(scale != 0); if (!QueryPerformanceCounter(&counter)) { - return 0; + uv_fatal_error(GetLastError(), "QueryPerformanceCounter"); } + assert(counter.QuadPart != 0); /* Because we have no guarantee about the order of magnitude of the * performance counter interval, integer math could cause this computation * to overflow. Therefore we resort to floating point math. */ - return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale); + double scaled_freq = (double)hrtime_frequency_ / scale; + double result = (double) counter.QuadPart / scaled_freq; + return (uint64_t) result; }