diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-16 23:18:46 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-16 23:22:08 -0800 |
| commit | ac9236de0bc9ed3000947ef6eeeae1cd874d3071 (patch) | |
| tree | 89aa198ae216bd2a6fc9a415a1fdb279e5057b1a | |
| parent | 415cf5d70ac5547664dcc471c27845bce84ad430 (diff) | |
| download | nng-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.
| -rw-r--r-- | src/platform/windows/win_clock.c | 22 |
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); + } } |
