summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-01-16 23:18:46 -0800
committerGarrett D'Amore <garrett@damore.org>2017-01-16 23:22:08 -0800
commitac9236de0bc9ed3000947ef6eeeae1cd874d3071 (patch)
tree89aa198ae216bd2a6fc9a415a1fdb279e5057b1a /src
parent415cf5d70ac5547664dcc471c27845bce84ad430 (diff)
downloadnng-ac9236de0bc9ed3000947ef6eeeae1cd874d3071.tar.gz
nng-ac9236de0bc9ed3000947ef6eeeae1cd874d3071.tar.bz2
nng-ac9236de0bc9ed3000947ef6eeeae1cd874d3071.zip
Windows clock fixes.
Sleep() on Win32 rounds *down*, leading to truncated timeouts. What we do is change our sleep routing to start incrementally sleeping by 1ms until the tick count is reached. This ensures we don't wake early. This problem affects condition variables too, which means that some timeouts may occur up to one clock tick early (15ish ms). This should not be a problem for most users, who should really only be setting timeouts in quantities of a second or greater.
Diffstat (limited to 'src')
-rw-r--r--src/platform/windows/win_clock.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/platform/windows/win_clock.c b/src/platform/windows/win_clock.c
index 6cf191ee..9064b5e2 100644
--- a/src/platform/windows/win_clock.c
+++ b/src/platform/windows/win_clock.c
@@ -20,9 +20,27 @@ nni_plat_clock(void)
void
-nni_plat_usleep(nni_duration usec)
+nni_plat_usleep(nni_duration dur)
{
- Sleep((DWORD) ((usec + 999) / 1000));
+ uint64_t exp;
+
+
+ // Convert duration to msec, rounding up.
+ dur += 999;
+ dur /= 1000;
+
+ exp = (uint64_t) GetTickCount64() + dur;
+
+ // Sleep() would be our preferred API, if it didn't have a nasty
+ // feature where it rounds *down*. We always want to sleep *at
+ // least* the requested amount of time, and never ever less.
+ // If we wind up sleeping less, then we will sleep(1) in the hope
+ // of waiting until the next clock tick.
+
+ Sleep((DWORD) dur);
+ while ((uint64_t) GetTickCount64() < exp) {
+ Sleep(1);
+ }
}