Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-21302: Add nanosleep() implementation for time.sleep() in Unix #28526

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In Unix operating systems, :func:`time.sleep` now uses the ``nanosleep()`` function, if ``clock_nanosleep()`` is not available but ``nanosleep()`` is available. ``nanosleep()`` allows to sleep with nanosecond precision.
12 changes: 11 additions & 1 deletion Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,8 @@ pysleep(_PyTime_t secs)
#ifndef MS_WINDOWS
#ifdef HAVE_CLOCK_NANOSLEEP
struct timespec timeout_abs;
#elif defined(HAVE_NANOSLEEP)
struct timespec timeout;
#else
struct timeval timeout;
#endif
Expand All @@ -2074,7 +2076,11 @@ pysleep(_PyTime_t secs)
#endif

do {
#ifndef HAVE_CLOCK_NANOSLEEP
#if defined(HAVE_NANOSLEEP) && !defined(HAVE_CLOCK_NANOSLEEP)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change LGTM, but I propose to write the #ifdef dance differently and rename secs to timeout to make the code more readable. I created PR #28545 based on your PR. Is it better? For the main code in Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, I merged the 3 code paths to put if #ifdef in the Py_BEGIN_ALLOW_THREADS block. What do you think?

if (_PyTime_AsTimespec(secs, &timeout) < 0) {
return -1;
}
#elif !defined(HAVE_CLOCK_NANOSLEEP)
if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) {
return -1;
}
Expand All @@ -2088,7 +2094,11 @@ pysleep(_PyTime_t secs)
err = ret;
#else
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_NANOSLEEP
ret = nanosleep(&timeout, NULL);
Livius90 marked this conversation as resolved.
Show resolved Hide resolved
#else
ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
#endif
Py_END_ALLOW_THREADS
err = errno;
#endif
Expand Down
58 changes: 58 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -13310,6 +13310,64 @@ fi
done


for ac_func in nanosleep
do :
ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
if test "x$ac_cv_func_nanosleep" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NANOSLEEP 1
_ACEOF

else

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5
$as_echo_n "checking for nanosleep in -lrt... " >&6; }
if ${ac_cv_lib_rt_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 nanosleep ();
int
main ()
{
return nanosleep ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_rt_nanosleep=yes
else
ac_cv_lib_rt_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_nanosleep" >&5
$as_echo "$ac_cv_lib_rt_nanosleep" >&6; }
if test "x$ac_cv_lib_rt_nanosleep" = xyes; then :

$as_echo "#define HAVE_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"
Expand Down
6 changes: 6 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4121,6 +4121,12 @@ AC_CHECK_FUNCS(clock_nanosleep, [], [
])
])

AC_CHECK_FUNCS(nanosleep, [], [
AC_CHECK_LIB(rt, nanosleep, [
AC_DEFINE(HAVE_NANOSLEEP, 1)
])
])

AC_MSG_CHECKING(for major, minor, and makedev)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if defined(MAJOR_IN_MKDEV)
Expand Down
3 changes: 3 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,9 @@
/* Define to 1 if you have the `mremap' function. */
#undef HAVE_MREMAP

/* Define to 1 if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP

/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H

Expand Down