From 86f1ca90e53883d8a3501c4df4af7be9e4f7b4f9 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 19 Jul 2011 14:56:23 +0200 Subject: [PATCH] Windows: implement uv_hrtime() --- src/win/error.c | 1 + src/win/timer.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/win/error.c b/src/win/error.c index d7cf9866c..d44be2bb2 100644 --- a/src/win/error.c +++ b/src/win/error.c @@ -107,6 +107,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; case WSAEMFILE: return UV_EMFILE; case ERROR_OUTOFMEMORY: return UV_ENOMEM; + case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; case ERROR_INVALID_FLAGS: return UV_EBADF; case ERROR_INVALID_PARAMETER: return UV_EINVAL; diff --git a/src/win/timer.c b/src/win/timer.c index 6f74a2ca0..d2ab89e93 100644 --- a/src/win/timer.c +++ b/src/win/timer.c @@ -26,10 +26,14 @@ #include "internal.h" #include "tree.h" +#undef NANOSEC +#define NANOSEC 1000000000 + /* The resolution of the high-resolution clock. */ static int64_t uv_ticks_per_msec_ = 0; - +static uint64_t uv_hrtime_frequency_ = 0; +static char uv_hrtime_initialized_ = 0; void uv_update_time() { @@ -48,8 +52,39 @@ int64_t uv_now() { uint64_t uv_hrtime(void) { - assert(0 && "implement me"); - return 0; + LARGE_INTEGER counter; + + /* When called for the first time, obtain the high-resolution clock */ + /* frequency. */ + if (!uv_hrtime_initialized_) { + uv_hrtime_initialized_ = 1; + + if (!QueryPerformanceFrequency(&counter)) { + uv_hrtime_frequency_ = 0; + uv_set_sys_error(GetLastError()); + return 0; + } + + uv_hrtime_frequency_ = counter.QuadPart; + } + + /* If the performance frequency is zero, there's no support. */ + if (!uv_hrtime_frequency_) { + uv_set_sys_error(ERROR_NOT_SUPPORTED); + return 0; + } + + if (!QueryPerformanceCounter(&counter)) { + uv_set_sys_error(GetLastError()); + return 0; + } + + /* Because we have no guarantee about the order of magniture 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 / uv_hrtime_frequency_) + + (((uint64_t) counter.HighPart * NANOSEC / uv_hrtime_frequency_) + << 32); }