diff --git a/Misc/NEWS b/Misc/NEWS index f604944eaa8..c9a40dfd4aa 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -124,6 +124,11 @@ Core and Builtins Library ------- +- Issue #22287: On UNIX, _PyTime_gettimeofday() now uses + clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now + depends on the librt library on Solaris and on Linux (only with glibc older + than 2.17). + - Issue #22182: Use e.args to unpack exceptions correctly in distutils.file_util.move_file. Patch by Claudiu Popa. diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d896091b01d..2b2b4bdc641 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1535,28 +1535,6 @@ static PyObject* floattime(_Py_clock_info_t *info) { _PyTime_timeval t; -#ifdef HAVE_CLOCK_GETTIME - struct timespec tp; - int ret; - - /* _PyTime_gettimeofday() does not use clock_gettime() - because it would require to link Python to the rt (real-time) - library, at least on Linux */ - ret = clock_gettime(CLOCK_REALTIME, &tp); - if (ret == 0) { - if (info) { - struct timespec res; - info->implementation = "clock_gettime(CLOCK_REALTIME)"; - info->monotonic = 0; - info->adjustable = 1; - if (clock_getres(CLOCK_REALTIME, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); - } -#endif _PyTime_gettimeofday_info(&t, info); return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6); } diff --git a/Python/pytime.c b/Python/pytime.c index de6a41fe00b..1f3fafb228a 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -56,8 +56,39 @@ pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info) fail, so we fall back on ftime() or time(). Note: clock resolution does not imply clock accuracy! */ -#ifdef HAVE_GETTIMEOFDAY +#if (defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY) \ + || defined(HAVE_FTIME)) int err; +#endif +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +#endif +#ifdef HAVE_FTIME + struct timeb t; +#endif + + /* test clock_gettime(CLOCK_REALTIME) */ +#ifdef HAVE_CLOCK_GETTIME + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err == 0) { + if (info) { + struct timespec res; + info->implementation = "clock_gettime(CLOCK_REALTIME)"; + info->monotonic = 0; + info->adjustable = 1; + if (clock_getres(CLOCK_REALTIME, &res) == 0) + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + else + info->resolution = 1e-9; + } + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; + return; + } +#endif + + /* test gettimeofday() */ +#ifdef HAVE_GETTIMEOFDAY #ifdef GETTIMEOFDAY_NO_TZ err = gettimeofday(tp); #else @@ -74,18 +105,15 @@ pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info) } #endif /* HAVE_GETTIMEOFDAY */ -#if defined(HAVE_FTIME) - { - struct timeb t; - ftime(&t); - tp->tv_sec = t.time; - tp->tv_usec = t.millitm * 1000; - if (info) { - info->implementation = "ftime()"; - info->resolution = 1e-3; - info->monotonic = 0; - info->adjustable = 1; - } +#ifdef HAVE_FTIME + ftime(&t); + tp->tv_sec = t.time; + tp->tv_usec = t.millitm * 1000; + if (info) { + info->implementation = "ftime()"; + info->resolution = 1e-3; + info->monotonic = 0; + info->adjustable = 1; } #else /* !HAVE_FTIME */ tp->tv_sec = time(NULL); diff --git a/configure b/configure index c4c5b7be6ca..4247a78f608 100755 --- a/configure +++ b/configure @@ -11904,6 +11904,7 @@ fi $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : + LIBS="$LIBS -lrt" $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index 086bdd4e486..05dc0e69c52 100644 --- a/configure.ac +++ b/configure.ac @@ -3319,6 +3319,7 @@ AC_CHECK_FUNCS(gettimeofday, AC_CHECK_FUNCS(clock_gettime, [], [ AC_CHECK_LIB(rt, clock_gettime, [ + LIBS="$LIBS -lrt" AC_DEFINE(HAVE_CLOCK_GETTIME, 1) AC_DEFINE(TIMEMODULE_LIB, [rt], [Library needed by timemodule.c: librt may be needed for clock_gettime()])