From eecf379b036439ae87df5d6e4a9bc37dedbb2bab Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Thu, 10 Jun 2021 21:27:48 -0700 Subject: [PATCH 1/2] Normalization of H5_nanosleep() with VFD SWMR branch --- src/H5system.c | 43 ++++++++++++++++++++++++++++++------------- src/H5win32defs.h | 1 - 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/H5system.c b/src/H5system.c index 7dd0b74a61f..06cfbf5262e 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -967,10 +967,7 @@ H5_combine_path(const char *path1, const char *path2, char **full_name /*out*/) * 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,41 @@ 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 3718121b90f..26bca675348 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 From b8555ae107ab5c4607fe75cf39196e47af988c7f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 11 Jun 2021 04:30:08 +0000 Subject: [PATCH 2/2] Committing clang-format changes --- src/H5system.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/H5system.c b/src/H5system.c index 06cfbf5262e..9d8772613e7 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -990,7 +990,6 @@ H5_nanosleep(uint64_t nanosec) const uint64_t nanosec_per_sec = 1000 * 1000 * 1000; struct timespec sleeptime; /* Struct to hold time to sleep */ - /* Set up time to sleep * * Assuming ILP32 or LP64 or wider architecture, (long)operand