Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 85a4748

Browse files
Livius90vstinner
andauthored
bpo-21302: Add clock_nanosleep() implementation for time.sleep() (GH-28111)
In Unix operating systems, time.sleep() now uses the clock_nanosleep() function, if available, which allows to sleep for an interval specified with nanosecond precision. Co-authored-by: Victor Stinner <[email protected]>
1 parent 3e19409 commit 85a4748

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
In Unix operating systems, :func:`time.sleep` now uses the ``clock_nanosleep()`` function,
2+
if available, which allows to sleep for an interval specified with nanosecond precision.

Modules/timemodule.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,8 +2053,13 @@ pysleep(_PyTime_t secs)
20532053
{
20542054
_PyTime_t deadline, monotonic;
20552055
#ifndef MS_WINDOWS
2056+
#ifdef HAVE_CLOCK_NANOSLEEP
2057+
struct timespec timeout_abs;
2058+
#else
20562059
struct timeval timeout;
2060+
#endif
20572061
int err = 0;
2062+
int ret = 0;
20582063
#else
20592064
_PyTime_t millisecs;
20602065
unsigned long ul_millis;
@@ -2066,20 +2071,38 @@ pysleep(_PyTime_t secs)
20662071
return -1;
20672072
}
20682073
deadline = monotonic + secs;
2074+
#if defined(HAVE_CLOCK_NANOSLEEP) && !defined(MS_WINDOWS)
2075+
if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
2076+
return -1;
2077+
}
2078+
#endif
20692079

20702080
do {
20712081
#ifndef MS_WINDOWS
2072-
if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0)
2082+
#ifndef HAVE_CLOCK_NANOSLEEP
2083+
if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) {
20732084
return -1;
2085+
}
2086+
#endif
20742087

2088+
#ifdef HAVE_CLOCK_NANOSLEEP
20752089
Py_BEGIN_ALLOW_THREADS
2076-
err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
2090+
ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
20772091
Py_END_ALLOW_THREADS
2092+
err = ret;
2093+
#else
2094+
Py_BEGIN_ALLOW_THREADS
2095+
ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
2096+
Py_END_ALLOW_THREADS
2097+
err = errno;
2098+
#endif
20782099

2079-
if (err == 0)
2100+
if (ret == 0) {
20802101
break;
2102+
}
20812103

2082-
if (errno != EINTR) {
2104+
if (err != EINTR) {
2105+
errno = err;
20832106
PyErr_SetFromErrno(PyExc_OSError);
20842107
return -1;
20852108
}
@@ -2114,9 +2137,11 @@ pysleep(_PyTime_t secs)
21142137
#endif
21152138

21162139
/* sleep was interrupted by SIGINT */
2117-
if (PyErr_CheckSignals())
2140+
if (PyErr_CheckSignals()) {
21182141
return -1;
2142+
}
21192143

2144+
#ifndef HAVE_CLOCK_NANOSLEEP
21202145
if (get_monotonic(&monotonic) < 0) {
21212146
return -1;
21222147
}
@@ -2125,6 +2150,7 @@ pysleep(_PyTime_t secs)
21252150
break;
21262151
}
21272152
/* retry with the recomputed delay */
2153+
#endif
21282154
} while (1);
21292155

21302156
return 0;

configure

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13252,6 +13252,64 @@ fi
1325213252
done
1325313253

1325413254

13255+
for ac_func in clock_nanosleep
13256+
do :
13257+
ac_fn_c_check_func "$LINENO" "clock_nanosleep" "ac_cv_func_clock_nanosleep"
13258+
if test "x$ac_cv_func_clock_nanosleep" = xyes; then :
13259+
cat >>confdefs.h <<_ACEOF
13260+
#define HAVE_CLOCK_NANOSLEEP 1
13261+
_ACEOF
13262+
13263+
else
13264+
13265+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_nanosleep in -lrt" >&5
13266+
$as_echo_n "checking for clock_nanosleep in -lrt... " >&6; }
13267+
if ${ac_cv_lib_rt_clock_nanosleep+:} false; then :
13268+
$as_echo_n "(cached) " >&6
13269+
else
13270+
ac_check_lib_save_LIBS=$LIBS
13271+
LIBS="-lrt $LIBS"
13272+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
13273+
/* end confdefs.h. */
13274+
13275+
/* Override any GCC internal prototype to avoid an error.
13276+
Use char because int might match the return type of a GCC
13277+
builtin and then its argument prototype would still apply. */
13278+
#ifdef __cplusplus
13279+
extern "C"
13280+
#endif
13281+
char clock_nanosleep ();
13282+
int
13283+
main ()
13284+
{
13285+
return clock_nanosleep ();
13286+
;
13287+
return 0;
13288+
}
13289+
_ACEOF
13290+
if ac_fn_c_try_link "$LINENO"; then :
13291+
ac_cv_lib_rt_clock_nanosleep=yes
13292+
else
13293+
ac_cv_lib_rt_clock_nanosleep=no
13294+
fi
13295+
rm -f core conftest.err conftest.$ac_objext \
13296+
conftest$ac_exeext conftest.$ac_ext
13297+
LIBS=$ac_check_lib_save_LIBS
13298+
fi
13299+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_nanosleep" >&5
13300+
$as_echo "$ac_cv_lib_rt_clock_nanosleep" >&6; }
13301+
if test "x$ac_cv_lib_rt_clock_nanosleep" = xyes; then :
13302+
13303+
$as_echo "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h
13304+
13305+
13306+
fi
13307+
13308+
13309+
fi
13310+
done
13311+
13312+
1325513313
for ac_func in clock_getres
1325613314
do :
1325713315
ac_fn_c_check_func "$LINENO" "clock_getres" "ac_cv_func_clock_getres"

configure.ac

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4115,6 +4115,12 @@ AC_CHECK_FUNCS(clock_settime, [], [
41154115
])
41164116
])
41174117

4118+
AC_CHECK_FUNCS(clock_nanosleep, [], [
4119+
AC_CHECK_LIB(rt, clock_nanosleep, [
4120+
AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1)
4121+
])
4122+
])
4123+
41184124
AC_MSG_CHECKING(for major, minor, and makedev)
41194125
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
41204126
#if defined(MAJOR_IN_MKDEV)

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@
136136
/* Define to 1 if you have the `clock' function. */
137137
#undef HAVE_CLOCK
138138

139+
/* Define to 1 if you have the `clock_nanosleep' function. */
140+
#undef HAVE_CLOCK_NANOSLEEP
141+
139142
/* Define to 1 if you have the `clock_getres' function. */
140143
#undef HAVE_CLOCK_GETRES
141144

0 commit comments

Comments
 (0)