closes bpo-31596: Add an interface for pthread_getcpuclockid(3) (#3756)
This commit is contained in:
parent
55fd06605b
commit
e14679c784
|
@ -162,6 +162,22 @@ The module defines the following functions and data items:
|
||||||
:func:`perf_counter` or :func:`process_time` instead, depending on your
|
:func:`perf_counter` or :func:`process_time` instead, depending on your
|
||||||
requirements, to have a well defined behaviour.
|
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)
|
.. function:: clock_getres(clk_id)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import platform
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import time
|
import time
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
|
@ -80,6 +81,25 @@ class TimeTestCase(unittest.TestCase):
|
||||||
b = time.clock_gettime(time.CLOCK_MONOTONIC)
|
b = time.clock_gettime(time.CLOCK_MONOTONIC)
|
||||||
self.assertLessEqual(a, b)
|
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'),
|
@unittest.skipUnless(hasattr(time, 'clock_getres'),
|
||||||
'need time.clock_getres()')
|
'need time.clock_getres()')
|
||||||
def test_clock_getres(self):
|
def test_clock_getres(self):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added pthread_getcpuclockid() to the time module
|
|
@ -20,6 +20,10 @@
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_PTHREAD_H)
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__WATCOMC__) && !defined(__QNX__)
|
#if defined(__WATCOMC__) && !defined(__QNX__)
|
||||||
#include <i86.h>
|
#include <i86.h>
|
||||||
#else
|
#else
|
||||||
|
@ -221,6 +225,31 @@ PyDoc_STRVAR(clock_getres_doc,
|
||||||
Return the resolution (precision) of the specified clock clk_id.");
|
Return the resolution (precision) of the specified clock clk_id.");
|
||||||
#endif /* HAVE_CLOCK_GETRES */
|
#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 *
|
static PyObject *
|
||||||
time_sleep(PyObject *self, PyObject *obj)
|
time_sleep(PyObject *self, PyObject *obj)
|
||||||
{
|
{
|
||||||
|
@ -1287,6 +1316,9 @@ static PyMethodDef time_methods[] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CLOCK_GETRES
|
#ifdef HAVE_CLOCK_GETRES
|
||||||
{"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc},
|
{"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
|
#endif
|
||||||
{"sleep", time_sleep, METH_O, sleep_doc},
|
{"sleep", time_sleep, METH_O, sleep_doc},
|
||||||
{"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},
|
{"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},
|
||||||
|
|
|
@ -10480,6 +10480,17 @@ if test "x$ac_cv_func_pthread_atfork" = xyes; then :
|
||||||
#define HAVE_PTHREAD_ATFORK 1
|
#define HAVE_PTHREAD_ATFORK 1
|
||||||
_ACEOF
|
_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
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -3025,6 +3025,7 @@ if test "$posix_threads" = "yes"; then
|
||||||
;;
|
;;
|
||||||
esac])
|
esac])
|
||||||
AC_CHECK_FUNCS(pthread_atfork)
|
AC_CHECK_FUNCS(pthread_atfork)
|
||||||
|
AC_CHECK_FUNCS(pthread_getcpuclockid)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -694,6 +694,9 @@
|
||||||
/* Defined for Solaris 2.6 bug in pthread header. */
|
/* Defined for Solaris 2.6 bug in pthread header. */
|
||||||
#undef HAVE_PTHREAD_DESTRUCTOR
|
#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. */
|
/* Define to 1 if you have the <pthread.h> header file. */
|
||||||
#undef HAVE_PTHREAD_H
|
#undef HAVE_PTHREAD_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue