Commit ec919cc7 authored by Victor Stinner's avatar Victor Stinner

Issue #10278: Drop time.monotonic() function, rename time.wallclock() to time.steady()

 * On Mac OS X, time.steady() now uses mach_absolute_time(), a monotonic clock
 * Optimistic change: bet that CLOCK_MONOTONIC and CLOCK_REALTIME are available
   when clock_gettime() is available
 * Rewrite time.steady() documentation
parent 5e545194
...@@ -226,11 +226,15 @@ The module defines the following functions and data items: ...@@ -226,11 +226,15 @@ The module defines the following functions and data items:
The earliest date for which it can generate a time is platform-dependent. The earliest date for which it can generate a time is platform-dependent.
.. function:: monotonic() .. function:: steady()
Monotonic non-decreasing clock. The clock is not related to the system clock .. index::
and cannot go backward. The reference point of the returned single: benchmarking
value is undefined so only the difference of consecutive calls is valid.
Return the current time as a floating point number expressed in seconds.
This clock advances at a steady rate relative to real time and it may not be
adjusted. The reference point of the returned value is undefined so only the
difference of consecutive calls is valid.
.. versionadded:: 3.3 .. versionadded:: 3.3
...@@ -547,20 +551,6 @@ The module defines the following functions and data items: ...@@ -547,20 +551,6 @@ The module defines the following functions and data items:
('EET', 'EEST') ('EET', 'EEST')
.. function:: wallclock()
.. index::
single: Wallclock
single: benchmarking
Return the current time in fractions of a second to the system's best ability.
Use this when the most accurate representation of wall-clock is required, i.e.
when "processor time" is inappropriate. The reference point of the returned
value is undefined so only the difference of consecutive calls is valid.
.. versionadded:: 3.3
.. seealso:: .. seealso::
Module :mod:`datetime` Module :mod:`datetime`
......
...@@ -943,8 +943,7 @@ The :mod:`time` module has new functions: ...@@ -943,8 +943,7 @@ The :mod:`time` module has new functions:
* :func:`~time.clock_getres` and :func:`~time.clock_gettime` functions and * :func:`~time.clock_getres` and :func:`~time.clock_gettime` functions and
``CLOCK_xxx`` constants. ``CLOCK_xxx`` constants.
* :func:`~time.monotonic`: monotonic clock. * :func:`~time.steady`.
* :func:`~time.wallclock`.
(Contributed by Victor Stinner in :issue:`10278`) (Contributed by Victor Stinner in :issue:`10278`)
......
...@@ -331,29 +331,10 @@ class TimeTestCase(unittest.TestCase): ...@@ -331,29 +331,10 @@ class TimeTestCase(unittest.TestCase):
pass pass
self.assertEqual(time.strftime('%Z', tt), tzname) self.assertEqual(time.strftime('%Z', tt), tzname)
@unittest.skipUnless(hasattr(time, 'monotonic'), def test_steady(self):
'need time.monotonic()') t1 = time.steady()
def test_monotonic(self):
t1 = time.monotonic()
t2 = time.monotonic()
self.assertGreaterEqual(t2, t1)
t1 = time.monotonic()
time.sleep(0.1) time.sleep(0.1)
t2 = time.monotonic() t2 = time.steady()
dt = t2 - t1
self.assertGreater(t2, t1)
self.assertAlmostEqual(dt, 0.1, delta=0.2)
def test_wallclock(self):
t1 = time.wallclock()
t2 = time.wallclock()
# may fail if the system clock was changed
self.assertGreaterEqual(t2, t1)
t1 = time.wallclock()
time.sleep(0.1)
t2 = time.wallclock()
dt = t2 - t1 dt = t2 - t1
# may fail if the system clock was changed # may fail if the system clock was changed
self.assertGreater(t2, t1) self.assertGreater(t2, t1)
......
...@@ -769,63 +769,10 @@ should not be relied on."); ...@@ -769,63 +769,10 @@ should not be relied on.");
#endif /* HAVE_WORKING_TZSET */ #endif /* HAVE_WORKING_TZSET */
static PyObject * static PyObject *
time_wallclock(PyObject *self, PyObject *unused) time_steady(PyObject *self, PyObject *unused)
{ {
#if defined(MS_WINDOWS) && !defined(__BORLANDC__) #if defined(MS_WINDOWS) && !defined(__BORLANDC__)
return win32_clock(1); return win32_clock(1);
#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
static int clk_index = 0;
clockid_t clk_ids[] = {
#ifdef CLOCK_MONOTONIC_RAW
CLOCK_MONOTONIC_RAW,
#endif
CLOCK_MONOTONIC
#ifdef CLOCK_REALTIME
/* On Linux, CLOCK_REALTIME uses the same clock than gettimeofday(),
but clock_gettime() has a nanosecond resolution. */
, CLOCK_REALTIME
#endif
};
int ret;
struct timespec tp;
while (0 <= clk_index) {
clockid_t clk_id = clk_ids[clk_index];
ret = clock_gettime(clk_id, &tp);
if (ret == 0)
return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
clk_index++;
if (Py_ARRAY_LENGTH(clk_ids) <= clk_index)
clk_index = -1;
}
return time_time(self, NULL);
#else
return time_time(self, NULL);
#endif
}
PyDoc_STRVAR(wallclock_doc,
"wallclock() -> float\n\
\n\
Return the current time in fractions of a second to the system's best\n\
ability. Use this when the most accurate representation of wall-clock is\n\
required, i.e. when \"processor time\" is inappropriate. The reference point\n\
of the returned value is undefined so only the difference of consecutive\n\
calls is valid.");
#if (defined(MS_WINDOWS) && !defined(__BORLANDC__)) \
|| (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) \
|| (defined(__APPLE__))
# define HAVE_PYTIME_MONOTONIC
#endif
#ifdef HAVE_PYTIME_MONOTONIC
static PyObject *
time_monotonic(PyObject *self, PyObject *unused)
{
#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
return win32_clock(0);
#elif defined(__APPLE__) #elif defined(__APPLE__)
uint64_t time = mach_absolute_time(); uint64_t time = mach_absolute_time();
double secs; double secs;
...@@ -837,13 +784,14 @@ time_monotonic(PyObject *self, PyObject *unused) ...@@ -837,13 +784,14 @@ time_monotonic(PyObject *self, PyObject *unused)
secs = (double)time * timebase.numer / timebase.denom * 1e-9; secs = (double)time * timebase.numer / timebase.denom * 1e-9;
return PyFloat_FromDouble(secs); return PyFloat_FromDouble(secs);
#else #elif defined(HAVE_CLOCK_GETTIME)
static int clk_index = 0; static int clk_index = 0;
clockid_t clk_ids[] = { clockid_t clk_ids[] = {
#ifdef CLOCK_MONOTONIC_RAW #ifdef CLOCK_MONOTONIC_RAW
CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW,
#endif #endif
CLOCK_MONOTONIC CLOCK_MONOTONIC,
CLOCK_REALTIME
}; };
int ret; int ret;
struct timespec tp; struct timespec tp;
...@@ -858,17 +806,20 @@ time_monotonic(PyObject *self, PyObject *unused) ...@@ -858,17 +806,20 @@ time_monotonic(PyObject *self, PyObject *unused)
if (Py_ARRAY_LENGTH(clk_ids) <= clk_index) if (Py_ARRAY_LENGTH(clk_ids) <= clk_index)
clk_index = -1; clk_index = -1;
} }
PyErr_SetFromErrno(PyExc_OSError); return time_time(self, NULL);
return NULL; #else
return time_time(self, NULL);
#endif #endif
} }
PyDoc_STRVAR(monotonic_doc, PyDoc_STRVAR(steady_doc,
"monotonic() -> float\n\ "steady() -> float\n\
\n\ \n\
Monotonic clock. The reference point of the returned value is undefined so\n\ Return the current time as a floating point number expressed in seconds.\n\
only the difference of consecutive calls is valid."); This clock advances at a steady rate relative to real time and it may not\n\
#endif be adjusted. The reference point of the returned value is undefined so only\n\
the difference of consecutive calls is valid.");
static void static void
PyInit_timezone(PyObject *m) { PyInit_timezone(PyObject *m) {
...@@ -998,9 +949,7 @@ static PyMethodDef time_methods[] = { ...@@ -998,9 +949,7 @@ static PyMethodDef time_methods[] = {
#ifdef HAVE_MKTIME #ifdef HAVE_MKTIME
{"mktime", time_mktime, METH_O, mktime_doc}, {"mktime", time_mktime, METH_O, mktime_doc},
#endif #endif
#ifdef HAVE_PYTIME_MONOTONIC {"steady", time_steady, METH_NOARGS, steady_doc},
{"monotonic", time_monotonic, METH_NOARGS, monotonic_doc},
#endif
#ifdef HAVE_STRFTIME #ifdef HAVE_STRFTIME
{"strftime", time_strftime, METH_VARARGS, strftime_doc}, {"strftime", time_strftime, METH_VARARGS, strftime_doc},
#endif #endif
...@@ -1008,7 +957,6 @@ static PyMethodDef time_methods[] = { ...@@ -1008,7 +957,6 @@ static PyMethodDef time_methods[] = {
#ifdef HAVE_WORKING_TZSET #ifdef HAVE_WORKING_TZSET
{"tzset", time_tzset, METH_NOARGS, tzset_doc}, {"tzset", time_tzset, METH_NOARGS, tzset_doc},
#endif #endif
{"wallclock", time_wallclock, METH_NOARGS, wallclock_doc},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment