[Python-checkins] closes bpo-31596: Add an interface for pthread_getcpuclockid(3) (#3756)

Benjamin Peterson webhook-mailer at python.org
Thu Oct 5 03:01:59 EDT 2017


https://github.com/python/cpython/commit/e14679c78464d1e0e16786c2a0e9bcebe49e842b
commit: e14679c78464d1e0e16786c2a0e9bcebe49e842b
branch: master
author: pdox <pdox at alum.mit.edu>
committer: Benjamin Peterson <benjamin at python.org>
date: 2017-10-05T00:01:56-07:00
summary:

closes bpo-31596: Add an interface for pthread_getcpuclockid(3) (#3756)

files:
A Misc/NEWS.d/next/Library/2017-09-26-11-38-52.bpo-31596.50Eyel.rst
M Doc/library/time.rst
M Lib/test/test_time.py
M Modules/timemodule.c
M configure
M configure.ac
M pyconfig.h.in

diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index ef0e69a5e8c..179762ed1c8 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -162,6 +162,22 @@ The module defines the following functions and data items:
       :func:`perf_counter` or :func:`process_time` instead, depending on your
       requirements, to have a well defined behaviour.
 
+.. function:: pthread_getcpuclockid(thread_id)
+
+   Return the *clk_id* of the thread-specific CPU-time clock for the specified *thread_id*.
+
+   Use :func:`threading.get_ident` or the :attr:`~threading.Thread.ident`
+   attribute of :class:`threading.Thread` objects to get a suitable value
+   for *thread_id*.
+
+   .. warning::
+      Passing an invalid or expired *thread_id* may result in
+      undefined behavior, such as segmentation fault.
+
+   Availability: Unix (see the man page for :manpage:`pthread_getcpuclockid(3)` for
+   further information)
+
+   .. versionadded:: 3.7
 
 .. function:: clock_getres(clk_id)
 
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index b2aedc3be50..1456748ed8e 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -7,6 +7,7 @@
 import sys
 import sysconfig
 import time
+import threading
 import unittest
 try:
     import _testcapi
@@ -80,6 +81,25 @@ def test_clock_monotonic(self):
         b = time.clock_gettime(time.CLOCK_MONOTONIC)
         self.assertLessEqual(a, b)
 
+    @unittest.skipUnless(hasattr(time, 'pthread_getcpuclockid'),
+                         'need time.pthread_getcpuclockid()')
+    @unittest.skipUnless(hasattr(time, 'clock_gettime'),
+                         'need time.clock_gettime()')
+    @unittest.skipUnless(hasattr(time, 'CLOCK_THREAD_CPUTIME_ID'),
+                         'need time.CLOCK_THREAD_CPUTIME_ID')
+    def test_pthread_getcpuclockid(self):
+        clk_id = time.pthread_getcpuclockid(threading.get_ident())
+        self.assertTrue(type(clk_id) is int)
+        self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
+        # This should suffice to show that both calls are measuring the same clock.
+        t1 = time.clock_gettime(clk_id)
+        t2 = time.clock_gettime(time.CLOCK_THREAD_CPUTIME_ID)
+        t3 = time.clock_gettime(clk_id)
+        t4 = time.clock_gettime(time.CLOCK_THREAD_CPUTIME_ID)
+        self.assertLessEqual(t1, t2)
+        self.assertLessEqual(t2, t3)
+        self.assertLessEqual(t3, t4)
+
     @unittest.skipUnless(hasattr(time, 'clock_getres'),
                          'need time.clock_getres()')
     def test_clock_getres(self):
diff --git a/Misc/NEWS.d/next/Library/2017-09-26-11-38-52.bpo-31596.50Eyel.rst b/Misc/NEWS.d/next/Library/2017-09-26-11-38-52.bpo-31596.50Eyel.rst
new file mode 100644
index 00000000000..85b1e1a8cad
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-09-26-11-38-52.bpo-31596.50Eyel.rst
@@ -0,0 +1 @@
+Added pthread_getcpuclockid() to the time module
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 36a95bbcedd..34e057d9d74 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -20,6 +20,10 @@
 #include <io.h>
 #endif
 
+#if defined(HAVE_PTHREAD_H)
+#  include <pthread.h>
+#endif
+
 #if defined(__WATCOMC__) && !defined(__QNX__)
 #include <i86.h>
 #else
@@ -221,6 +225,31 @@ PyDoc_STRVAR(clock_getres_doc,
 Return the resolution (precision) of the specified clock clk_id.");
 #endif   /* HAVE_CLOCK_GETRES */
 
+#ifdef HAVE_PTHREAD_GETCPUCLOCKID
+static PyObject *
+time_pthread_getcpuclockid(PyObject *self, PyObject *args)
+{
+    unsigned long thread_id;
+    int err;
+    clockid_t clk_id;
+    if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
+        return NULL;
+    }
+    err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
+    if (err) {
+        errno = err;
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    return PyLong_FromLong(clk_id);
+}
+
+PyDoc_STRVAR(pthread_getcpuclockid_doc,
+"pthread_getcpuclockid(thread_id) -> int\n\
+\n\
+Return the clk_id of a thread's CPU time clock.");
+#endif /* HAVE_PTHREAD_GETCPUCLOCKID */
+
 static PyObject *
 time_sleep(PyObject *self, PyObject *obj)
 {
@@ -1288,6 +1317,9 @@ static PyMethodDef time_methods[] = {
 #ifdef HAVE_CLOCK_GETRES
     {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
 #endif
+#ifdef HAVE_PTHREAD_GETCPUCLOCKID
+    {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
+#endif
     {"sleep",           time_sleep, METH_O, sleep_doc},
     {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
     {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
diff --git a/configure b/configure
index 8a763ef6e49..2d1bed22476 100755
--- a/configure
+++ b/configure
@@ -10483,6 +10483,17 @@ _ACEOF
 fi
 done
 
+      for ac_func in pthread_getcpuclockid
+do :
+  ac_fn_c_check_func "$LINENO" "pthread_getcpuclockid" "ac_cv_func_pthread_getcpuclockid"
+if test "x$ac_cv_func_pthread_getcpuclockid" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PTHREAD_GETCPUCLOCKID 1
+_ACEOF
+
+fi
+done
+
 fi
 
 
diff --git a/configure.ac b/configure.ac
index 41bd9effbfd..b562fe405a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3025,6 +3025,7 @@ if test "$posix_threads" = "yes"; then
             ;;
         esac])
       AC_CHECK_FUNCS(pthread_atfork)
+      AC_CHECK_FUNCS(pthread_getcpuclockid)
 fi
 
 
diff --git a/pyconfig.h.in b/pyconfig.h.in
index d4feabeece3..637341afee3 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -694,6 +694,9 @@
 /* Defined for Solaris 2.6 bug in pthread header. */
 #undef HAVE_PTHREAD_DESTRUCTOR
 
+/* Define to 1 if you have the `pthread_getcpuclockid' function. */
+#undef HAVE_PTHREAD_GETCPUCLOCKID
+
 /* Define to 1 if you have the <pthread.h> header file. */
 #undef HAVE_PTHREAD_H
 



More information about the Python-checkins mailing list