summaryrefslogtreecommitdiffstats
path: root/src/H5system.c
diff options
context:
space:
mode:
authorDana Robinson <43805+derobins@users.noreply.github.com>2021-06-11 22:02:43 (GMT)
committerGitHub <noreply@github.com>2021-06-11 22:02:43 (GMT)
commit3c18cf7831facc924f0f88c55284d721c9999640 (patch)
tree459e84ffb9d594b6082ba9eb82351b390b7fa6e2 /src/H5system.c
parent03fb540c72fe49ca6240056c46e3b62d849204f4 (diff)
downloadhdf5-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>
Diffstat (limited to 'src/H5system.c')
-rw-r--r--src/H5system.c42
1 files changed, 29 insertions, 13 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