diff --git a/Doc/library/time.rst b/Doc/library/time.rst --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -136,6 +136,48 @@ The module defines the following functio microsecond. +.. function:: clock_gettime(clk_id) + + Return the time of the specified clock *clk_id*. + + .. versionadded:: 3.3 + +.. data:: CLOCK_REALTIME + + System-wide real-time clock. Setting this clock requires appropriate + privileges. + + .. versionadded:: 3.3 + +.. data:: CLOCK_MONOTONIC + + Clock that cannot be set and represents monotonic time since some + unspecified starting point. + + .. versionadded:: 3.3 + +.. data:: CLOCK_MONOTONIC_RAW + + Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw + hardware-based time that is not subject to NTP adjustments. + + Availability: Linux 2.6.28 or later. + + .. versionadded:: 3.3 + +.. data:: CLOCK_PROCESS_CPUTIME_ID + + High-resolution per-process timer from the CPU. + + .. versionadded:: 3.3 + +.. data:: CLOCK_THREAD_CPUTIME_ID + + Thread-specific CPU-time clock. + + .. versionadded:: 3.3 + + .. function:: ctime([secs]) Convert a time expressed in seconds since the epoch to a string representing diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -264,6 +264,14 @@ shutil path also specifying the user/group names and not only their numeric ids. (Contributed by Sandro Tosi in :issue:`12191`) +time +---- + +* The :mod:`time` module has a new :func:`~time.clock_gettime` function. With + :data:`time.CLOCK_MONOTONIC`, it can be used to get a monotonic clock. + + (Contributed by Victor Stinner in :issue:`10278`) + Optimizations ============= diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -20,6 +20,15 @@ class TimeTestCase(unittest.TestCase): def test_clock(self): time.clock() + @unittest.skipUnless(hasattr(time, 'clock_gettime'), + 'need time.clock_gettime()') + @unittest.skipUnless(hasattr(time, 'CLOCK_MONOTONIC'), + 'need time.CLOCK_MONOTONIC') + def test_clock(self): + a = time.clock_gettime(time.CLOCK_MONOTONIC) + b = time.clock_gettime(time.CLOCK_MONOTONIC) + self.assertLessEqual(a, b) + def test_conversions(self): self.assertEqual(time.ctime(self.t), time.asctime(time.localtime(self.t))) diff --git a/Modules/timemodule.c b/Modules/timemodule.c --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -135,6 +135,30 @@ the first call to clock(). This has as records."); #endif +#ifdef HAVE_CLOCK_GETTIME +static PyObject * +time_clock_gettime(PyObject *self, PyObject *args) +{ + int ret; + clockid_t clk_id; + struct timespec tp; + + if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) + return NULL; + + ret = clock_gettime((clockid_t)clk_id, &tp); + if (ret != 0) + PyErr_SetFromErrno(PyExc_IOError); + + return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); +} + +PyDoc_STRVAR(clock_gettime_doc, +"clock_gettime(clk_id) -> floating point number\n\ +\n\ +Return the time of the specified clock clk_id."); +#endif + static PyObject * time_sleep(PyObject *self, PyObject *args) { @@ -780,6 +804,24 @@ PyInit_timezone(PyObject *m) { Py_BuildValue("(zz)", _tzname[0], _tzname[1])); #endif /* __CYGWIN__ */ #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ + +#ifdef HAVE_CLOCK_GETTIME +#ifdef CLOCK_REALTIME + PyModule_AddIntMacro(m, CLOCK_REALTIME); +#endif +#ifdef CLOCK_MONOTONIC + PyModule_AddIntMacro(m, CLOCK_MONOTONIC); +#endif +#ifdef CLOCK_MONOTONIC_RAW + PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW); +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID); +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID); +#endif +#endif /* HAVE_CLOCK_GETTIME */ } @@ -788,6 +830,9 @@ static PyMethodDef time_methods[] = { #if (defined(MS_WINDOWS) && !defined(__BORLANDC__)) || defined(HAVE_CLOCK) {"clock", time_clock, METH_NOARGS, clock_doc}, #endif +#ifdef HAVE_CLOCK_GETTIME + {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, +#endif {"sleep", time_sleep, METH_VARARGS, sleep_doc}, {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, {"localtime", time_localtime, METH_VARARGS, localtime_doc}, diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2819,6 +2819,13 @@ AC_CHECK_FUNCS(gettimeofday, ]) ) +AC_CHECK_FUNCS(clock_gettime, [], [ + AC_CHECK_LIB(rt, clock_gettime, [ + AC_DEFINE(HAVE_CLOCK_GETTIME, 1) + AC_DEFINE(TIMEMODULE_LIBS, [rt], [Libraries needed by timemodule.c]) + ]) +]) + 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 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -113,6 +113,9 @@ /* Define to 1 if you have the `clock' function. */ #undef HAVE_CLOCK +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + /* Define if the C compiler supports computed gotos. */ #undef HAVE_COMPUTED_GOTOS @@ -1193,6 +1196,9 @@ /* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */ #undef TANH_PRESERVES_ZERO_SIGN +/* Libraries needed by timemodule.c */ +#undef TIMEMODULE_LIBS + /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -504,11 +504,17 @@ class PyBuildExt(build_ext): exts.append( Extension('math', ['mathmodule.c', '_math.c'], depends=['_math.h'], libraries=math_libs) ) + + # Check for MacOS X, which doesn't need libm.a at all + time_libs = [] + lib = sysconfig.get_config_var('TIMEMODULE_LIBS') + if lib: + time_libs.append(lib) + # time operations and variables exts.append( Extension('time', ['timemodule.c', '_time.c'], - libraries=math_libs) ) - exts.append( Extension('_datetime', ['_datetimemodule.c', '_time.c'], - libraries=math_libs) ) + libraries=time_libs) ) + exts.append( Extension('_datetime', ['_datetimemodule.c', '_time.c']) ) # random number generator implemented in C exts.append( Extension("_random", ["_randommodule.c"]) ) # bisect

AltStyle によって変換されたページ (->オリジナル) /