From 017efd14ab3ad880be89b716d55cc08cdeca1c34 Mon Sep 17 00:00:00 2001 From: Livius Date: Tue, 31 Aug 2021 00:31:15 +0200 Subject: [PATCH] clock_nanosleep() implementation for time.sleep() clock_nanosleep() is available in Linux which has POSIX 2001.12 or newer. --- Modules/timemodule.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 4caacc3b64d7c8..d004c32706a023 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -60,6 +60,10 @@ # define HAVE_CLOCK_GETTIME_RUNTIME 1 #endif +#if (!defined(MS_WINDOWS) && defined(__linux__) && defined(_POSIX_VERSION)) && (_POSIX_VERSION >= 200112L) +# define HAVE_CLOCK_NANOSLEEP 1 +#endif + #define SEC_TO_NS (1000 * 1000 * 1000) /* Forward declarations */ @@ -2044,6 +2048,23 @@ PyInit_time(void) return PyModuleDef_Init(&timemodule); } +#ifndef MS_WINDOWS +static int +sleep_unix(struct timeval timeout) +{ + int ret = 0; +#ifdef HAVE_CLOCK_NANOSLEEP + struct timespec request; + request.tv_sec = timeout.tv_sec; + request.tv_nsec = (long)(timeout.tv_usec) * 1000; + ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL); +#else + ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); +#endif + return ret; +} +#endif + /* Implement pysleep() for various platforms. When interrupted (or when another error occurs), return -1 and set an exception; else return 0. */ @@ -2073,7 +2094,7 @@ pysleep(_PyTime_t secs) return -1; Py_BEGIN_ALLOW_THREADS - err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); + err = sleep_unix(timeout); Py_END_ALLOW_THREADS if (err == 0)