diff --git a/src/win/util.c b/src/win/util.c index a8183438..266b8816 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -59,20 +59,24 @@ static char *process_title; static CRITICAL_SECTION process_title_lock; -/* The tick frequency of the high-resolution clock. */ -static uint64_t hrtime_frequency_ = 0; +/* Frequency (ticks per nanosecond) of the high-resolution clock. */ +static double hrtime_frequency_ = 0; /* * One-time intialization code for functionality defined in util.c. */ void uv__util_init() { + LARGE_INTEGER perf_frequency; + /* Initialize process title access mutex. */ InitializeCriticalSection(&process_title_lock); /* Retrieve high-resolution timer frequency. */ - if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_)) - hrtime_frequency_ = 0; + if (QueryPerformanceFrequency(&perf_frequency)) + hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC; + else + hrtime_frequency_= 0; } @@ -447,7 +451,7 @@ uint64_t uv_hrtime(void) { uv__once_init(); /* If the performance frequency is zero, there's no support. */ - if (!hrtime_frequency_) { + if (hrtime_frequency_ == 0) { /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */ return 0; } @@ -457,12 +461,11 @@ uint64_t uv_hrtime(void) { return 0; } - /* Because we have no guarantee about the order of magnitude of the */ - /* performance counter frequency, and there may not be much headroom to */ - /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */ - return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) + - (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_) - << 32); + /* Because we have no guarantee about the order of magnitude of the + * performance counter frequency, integer math could cause this computation + * to overflow. Therefore we resort to floating point math. + */ + return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_); }