diff options
author | Dana Robinson <43805+derobins@users.noreply.github.com> | 2021-06-11 22:02:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-11 22:02:43 (GMT) |
commit | 3c18cf7831facc924f0f88c55284d721c9999640 (patch) | |
tree | 459e84ffb9d594b6082ba9eb82351b390b7fa6e2 | |
parent | 03fb540c72fe49ca6240056c46e3b62d849204f4 (diff) | |
download | hdf5-3c18cf7831facc924f0f88c55284d721c9999640.zip hdf5-3c18cf7831facc924f0f88c55284d721c9999640.tar.gz hdf5-3c18cf7831facc924f0f88c55284d721c9999640.tar.bz2 |
Normalization of H5_nanosleep() with VFD SWMR branch (#746)
* Normalization of H5_nanosleep() with VFD SWMR branch
* Committing clang-format changes
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
-rw-r--r-- | src/H5system.c | 42 | ||||
-rw-r--r-- | src/H5win32defs.h | 1 |
2 files changed, 29 insertions, 14 deletions
diff --git a/src/H5system.c b/src/H5system.c index 7dd0b74..9d87726 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -967,10 +967,7 @@ done: * Note that commodity hardware is probably going to have a * resolution of milliseconds, not nanoseconds. * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * October 01, 2016 + * Return: void *-------------------------------------------------------------------------- */ void @@ -979,21 +976,40 @@ H5_nanosleep(uint64_t nanosec) FUNC_ENTER_NOAPI_NOINIT_NOERR #ifdef H5_HAVE_WIN32_API + DWORD dwMilliseconds = (DWORD)HDceil(nanosec / 1.0e6); + DWORD ignore; - /* On Windows, Sleep() is in milliseconds. Passing 0 to Sleep() - * causes the thread to relinquish the rest of its time slice. + /* Windows can't sleep at a ns resolution. Best we can do is ~1 ms. We + * don't care about the return value since the second parameter + * (bAlertable) is FALSE, so it will always be zero. */ - Sleep(nanosec / (1000 * 1000)); + ignore = SleepEx(dwMilliseconds, FALSE); #else - { - struct timespec sleeptime; /* Struct to hold time to sleep */ - /* Set up time to sleep */ - sleeptime.tv_sec = 0; - sleeptime.tv_nsec = (long)nanosec; + const uint64_t nanosec_per_sec = 1000 * 1000 * 1000; + struct timespec sleeptime; /* Struct to hold time to sleep */ - HDnanosleep(&sleeptime, NULL); + /* Set up time to sleep + * + * Assuming ILP32 or LP64 or wider architecture, (long)operand + * satisfies 0 <= operand < nanosec_per_sec < LONG_MAX. + * + * It's harder to be sure that we don't overflow time_t. + */ + sleeptime.tv_sec = (time_t)(nanosec / nanosec_per_sec); + sleeptime.tv_nsec = (long)(nanosec % nanosec_per_sec); + + /* Sleep for up to `sleeptime` and, in the event of an interruption, + * save the unslept time back to `sleeptime`. + */ + while (HDnanosleep(&sleeptime, &sleeptime) == -1) { + /* If we were just interrupted, sleep for the remaining time. + * Otherwise, the error was essentially impossible, so just stop + * sleeping. + */ + if (errno != EINTR) + break; } #endif diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 3718121..26bca67 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -45,7 +45,6 @@ typedef __int64 h5_stat_size_t; #define HDlseek(F, O, W) _lseeki64(F, O, W) #define HDlstat(S, B) _lstati64(S, B) #define HDmkdir(S, M) _mkdir(S) -#define HDnanosleep(N, O) Wnanosleep(N, O) #define HDoff_t __int64 /* Note that the variadic HDopen macro is using a VC++ extension |