summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS.d/next/Library/2021-09-11-18-44-40.bpo-21302.QxHRpR.rst2
-rw-r--r--Modules/timemodule.c36
-rwxr-xr-xconfigure58
-rw-r--r--configure.ac6
-rw-r--r--pyconfig.h.in3
5 files changed, 100 insertions, 5 deletions
diff --git a/Misc/NEWS.d/next/Library/2021-09-11-18-44-40.bpo-21302.QxHRpR.rst b/Misc/NEWS.d/next/Library/2021-09-11-18-44-40.bpo-21302.QxHRpR.rst
new file mode 100644
index 0000000..86f0a5a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-09-11-18-44-40.bpo-21302.QxHRpR.rst
@@ -0,0 +1,2 @@
+In Unix operating systems, :func:`time.sleep` now uses the ``clock_nanosleep()`` function,
+if available, which allows to sleep for an interval specified with nanosecond precision. \ No newline at end of file
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 4caacc3..cf58a18 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -2053,8 +2053,13 @@ pysleep(_PyTime_t secs)
{
_PyTime_t deadline, monotonic;
#ifndef MS_WINDOWS
+#ifdef HAVE_CLOCK_NANOSLEEP
+ struct timespec timeout_abs;
+#else
struct timeval timeout;
+#endif
int err = 0;
+ int ret = 0;
#else
_PyTime_t millisecs;
unsigned long ul_millis;
@@ -2066,20 +2071,38 @@ pysleep(_PyTime_t secs)
return -1;
}
deadline = monotonic + secs;
+#if defined(HAVE_CLOCK_NANOSLEEP) && !defined(MS_WINDOWS)
+ if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
+ return -1;
+ }
+#endif
do {
#ifndef MS_WINDOWS
- if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0)
+#ifndef HAVE_CLOCK_NANOSLEEP
+ if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) {
return -1;
+ }
+#endif
+#ifdef HAVE_CLOCK_NANOSLEEP
Py_BEGIN_ALLOW_THREADS
- err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
Py_END_ALLOW_THREADS
+ err = ret;
+#else
+ Py_BEGIN_ALLOW_THREADS
+ ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
+ Py_END_ALLOW_THREADS
+ err = errno;
+#endif
- if (err == 0)
+ if (ret == 0) {
break;
+ }
- if (errno != EINTR) {
+ if (err != EINTR) {
+ errno = err;
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
@@ -2114,9 +2137,11 @@ pysleep(_PyTime_t secs)
#endif
/* sleep was interrupted by SIGINT */
- if (PyErr_CheckSignals())
+ if (PyErr_CheckSignals()) {
return -1;
+ }
+#ifndef HAVE_CLOCK_NANOSLEEP
if (get_monotonic(&monotonic) < 0) {
return -1;
}
@@ -2125,6 +2150,7 @@ pysleep(_PyTime_t secs)
break;
}
/* retry with the recomputed delay */
+#endif
} while (1);
return 0;
diff --git a/configure b/configure
index 4f12972..2e3c9ba 100755
--- a/configure
+++ b/configure
@@ -13252,6 +13252,64 @@ fi
done
+for ac_func in clock_nanosleep
+do :
+ ac_fn_c_check_func "$LINENO" "clock_nanosleep" "ac_cv_func_clock_nanosleep"
+if test "x$ac_cv_func_clock_nanosleep" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_NANOSLEEP 1
+_ACEOF
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_nanosleep in -lrt" >&5
+$as_echo_n "checking for clock_nanosleep in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_nanosleep+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_nanosleep ();
+int
+main ()
+{
+return clock_nanosleep ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_clock_nanosleep=yes
+else
+ ac_cv_lib_rt_clock_nanosleep=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_nanosleep" >&5
+$as_echo "$ac_cv_lib_rt_clock_nanosleep" >&6; }
+if test "x$ac_cv_lib_rt_clock_nanosleep" = xyes; then :
+
+ $as_echo "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h
+
+
+fi
+
+
+fi
+done
+
+
for ac_func in clock_getres
do :
ac_fn_c_check_func "$LINENO" "clock_getres" "ac_cv_func_clock_getres"
diff --git a/configure.ac b/configure.ac
index bcb2054..4a0694c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4115,6 +4115,12 @@ AC_CHECK_FUNCS(clock_settime, [], [
])
])
+AC_CHECK_FUNCS(clock_nanosleep, [], [
+ AC_CHECK_LIB(rt, clock_nanosleep, [
+ AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1)
+ ])
+])
+
AC_MSG_CHECKING(for major, minor, and makedev)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if defined(MAJOR_IN_MKDEV)
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 49407ab..d6408e9 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -136,6 +136,9 @@
/* Define to 1 if you have the `clock' function. */
#undef HAVE_CLOCK
+/* Define to 1 if you have the `clock_nanosleep' function. */
+#undef HAVE_CLOCK_NANOSLEEP
+
/* Define to 1 if you have the `clock_getres' function. */
#undef HAVE_CLOCK_GETRES