mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-112567: Add _Py_GetTicksPerSecond() function (#112587)
* Move _PyRuntimeState.time to _posixstate.ticks_per_second and time_module_state.ticks_per_second. * Add time_module_state.clocks_per_second. * Rename _PyTime_GetClockWithInfo() to py_clock(). * Rename _PyTime_GetProcessTimeWithInfo() to py_process_time(). * Add process_time_times() helper function, called by py_process_time(). * os.times() is now always built: no longer rely on HAVE_TIMES.
This commit is contained in:
parent
a9073564ee
commit
05a370abd6
9 changed files with 142 additions and 125 deletions
|
@ -320,6 +320,10 @@ PyAPI_FUNC(char*) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject
|
||||||
|
|
||||||
extern int _PyFile_Flush(PyObject *);
|
extern int _PyFile_Flush(PyObject *);
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
extern int _Py_GetTicksPerSecond(long *ticks_per_second);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,7 +40,6 @@ extern void _PySys_FiniTypes(PyInterpreterState *interp);
|
||||||
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
||||||
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
||||||
|
|
||||||
extern PyStatus _PyTime_Init(void);
|
|
||||||
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
|
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
|
||||||
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
|
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
|
||||||
extern int _Py_Deepfreeze_Init(void);
|
extern int _Py_Deepfreeze_Init(void);
|
||||||
|
|
|
@ -21,7 +21,6 @@ extern "C" {
|
||||||
#include "pycore_pymem.h" // struct _pymem_allocators
|
#include "pycore_pymem.h" // struct _pymem_allocators
|
||||||
#include "pycore_pythread.h" // struct _pythread_runtime_state
|
#include "pycore_pythread.h" // struct _pythread_runtime_state
|
||||||
#include "pycore_signal.h" // struct _signals_runtime_state
|
#include "pycore_signal.h" // struct _signals_runtime_state
|
||||||
#include "pycore_time.h" // struct _time_runtime_state
|
|
||||||
#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state
|
#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state
|
||||||
#include "pycore_typeobject.h" // struct _types_runtime_state
|
#include "pycore_typeobject.h" // struct _types_runtime_state
|
||||||
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state
|
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state
|
||||||
|
@ -205,7 +204,6 @@ typedef struct pyruntimestate {
|
||||||
struct _pymem_allocators allocators;
|
struct _pymem_allocators allocators;
|
||||||
struct _obmalloc_global_state obmalloc;
|
struct _obmalloc_global_state obmalloc;
|
||||||
struct pyhash_runtime_state pyhash_state;
|
struct pyhash_runtime_state pyhash_state;
|
||||||
struct _time_runtime_state time;
|
|
||||||
struct _pythread_runtime_state threads;
|
struct _pythread_runtime_state threads;
|
||||||
struct _signals_runtime_state signals;
|
struct _signals_runtime_state signals;
|
||||||
|
|
||||||
|
|
|
@ -52,16 +52,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct _time_runtime_state {
|
|
||||||
#ifdef HAVE_TIMES
|
|
||||||
int ticks_per_second_initialized;
|
|
||||||
long ticks_per_second;
|
|
||||||
#else
|
|
||||||
int _not_used;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
struct timeval;
|
struct timeval;
|
||||||
#endif
|
#endif
|
||||||
|
|
10
Modules/clinic/posixmodule.c.h
generated
10
Modules/clinic/posixmodule.c.h
generated
|
@ -5997,8 +5997,6 @@ exit:
|
||||||
|
|
||||||
#endif /* defined(HAVE_SYMLINK) */
|
#endif /* defined(HAVE_SYMLINK) */
|
||||||
|
|
||||||
#if defined(HAVE_TIMES)
|
|
||||||
|
|
||||||
PyDoc_STRVAR(os_times__doc__,
|
PyDoc_STRVAR(os_times__doc__,
|
||||||
"times($module, /)\n"
|
"times($module, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -6021,8 +6019,6 @@ os_times(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
return os_times_impl(module);
|
return os_times_impl(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(HAVE_TIMES) */
|
|
||||||
|
|
||||||
#if defined(HAVE_TIMERFD_CREATE)
|
#if defined(HAVE_TIMERFD_CREATE)
|
||||||
|
|
||||||
PyDoc_STRVAR(os_timerfd_create__doc__,
|
PyDoc_STRVAR(os_timerfd_create__doc__,
|
||||||
|
@ -12116,10 +12112,6 @@ exit:
|
||||||
#define OS_SYMLINK_METHODDEF
|
#define OS_SYMLINK_METHODDEF
|
||||||
#endif /* !defined(OS_SYMLINK_METHODDEF) */
|
#endif /* !defined(OS_SYMLINK_METHODDEF) */
|
||||||
|
|
||||||
#ifndef OS_TIMES_METHODDEF
|
|
||||||
#define OS_TIMES_METHODDEF
|
|
||||||
#endif /* !defined(OS_TIMES_METHODDEF) */
|
|
||||||
|
|
||||||
#ifndef OS_TIMERFD_CREATE_METHODDEF
|
#ifndef OS_TIMERFD_CREATE_METHODDEF
|
||||||
#define OS_TIMERFD_CREATE_METHODDEF
|
#define OS_TIMERFD_CREATE_METHODDEF
|
||||||
#endif /* !defined(OS_TIMERFD_CREATE_METHODDEF) */
|
#endif /* !defined(OS_TIMERFD_CREATE_METHODDEF) */
|
||||||
|
@ -12403,4 +12395,4 @@ exit:
|
||||||
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||||
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
|
||||||
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
|
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
|
||||||
/*[clinic end generated code: output=0f216bf44ea358f9 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=2900675ac5219924 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -1030,6 +1030,10 @@ typedef struct {
|
||||||
PyObject *struct_rusage;
|
PyObject *struct_rusage;
|
||||||
#endif
|
#endif
|
||||||
PyObject *st_mode;
|
PyObject *st_mode;
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
// times() clock frequency in hertz; used by os.times()
|
||||||
|
long ticks_per_second;
|
||||||
|
#endif
|
||||||
} _posixstate;
|
} _posixstate;
|
||||||
|
|
||||||
|
|
||||||
|
@ -9986,8 +9990,6 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
|
||||||
#endif /* HAVE_SYMLINK */
|
#endif /* HAVE_SYMLINK */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static PyStructSequence_Field times_result_fields[] = {
|
static PyStructSequence_Field times_result_fields[] = {
|
||||||
{"user", "user time"},
|
{"user", "user time"},
|
||||||
{"system", "system time"},
|
{"system", "system time"},
|
||||||
|
@ -10013,12 +10015,6 @@ static PyStructSequence_Desc times_result_desc = {
|
||||||
5
|
5
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
#define HAVE_TIMES /* mandatory, for the method table */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TIMES
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
build_times_result(PyObject *module, double user, double system,
|
build_times_result(PyObject *module, double user, double system,
|
||||||
double children_user, double children_system,
|
double children_user, double children_system,
|
||||||
|
@ -10064,8 +10060,8 @@ All fields are floating point numbers.
|
||||||
static PyObject *
|
static PyObject *
|
||||||
os_times_impl(PyObject *module)
|
os_times_impl(PyObject *module)
|
||||||
/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
|
/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
{
|
{
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
FILETIME create, exit, kernel, user;
|
FILETIME create, exit, kernel, user;
|
||||||
HANDLE hProc;
|
HANDLE hProc;
|
||||||
hProc = GetCurrentProcess();
|
hProc = GetCurrentProcess();
|
||||||
|
@ -10083,28 +10079,26 @@ os_times_impl(PyObject *module)
|
||||||
(double)0,
|
(double)0,
|
||||||
(double)0,
|
(double)0,
|
||||||
(double)0);
|
(double)0);
|
||||||
}
|
|
||||||
#else /* MS_WINDOWS */
|
#else /* MS_WINDOWS */
|
||||||
{
|
_posixstate *state = get_posix_state(module);
|
||||||
struct tms t;
|
long ticks_per_second = state->ticks_per_second;
|
||||||
clock_t c;
|
|
||||||
|
struct tms process;
|
||||||
|
clock_t elapsed;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
c = times(&t);
|
elapsed = times(&process);
|
||||||
if (c == (clock_t) -1) {
|
if (elapsed == (clock_t) -1) {
|
||||||
return posix_error();
|
return posix_error();
|
||||||
}
|
}
|
||||||
assert(_PyRuntime.time.ticks_per_second_initialized);
|
|
||||||
#define ticks_per_second _PyRuntime.time.ticks_per_second
|
|
||||||
return build_times_result(module,
|
return build_times_result(module,
|
||||||
(double)t.tms_utime / ticks_per_second,
|
(double)process.tms_utime / ticks_per_second,
|
||||||
(double)t.tms_stime / ticks_per_second,
|
(double)process.tms_stime / ticks_per_second,
|
||||||
(double)t.tms_cutime / ticks_per_second,
|
(double)process.tms_cutime / ticks_per_second,
|
||||||
(double)t.tms_cstime / ticks_per_second,
|
(double)process.tms_cstime / ticks_per_second,
|
||||||
(double)c / ticks_per_second);
|
(double)elapsed / ticks_per_second);
|
||||||
#undef ticks_per_second
|
|
||||||
}
|
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
#endif /* HAVE_TIMES */
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_TIMERFD_CREATE)
|
#if defined(HAVE_TIMERFD_CREATE)
|
||||||
|
@ -17279,6 +17273,15 @@ posixmodule_exec(PyObject *m)
|
||||||
Py_DECREF(unicode);
|
Py_DECREF(unicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
if (_Py_GetTicksPerSecond(&state->ticks_per_second) < 0) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"cannot read ticks_per_second");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
assert(state->ticks_per_second >= 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
return PyModule_Add(m, "_have_functions", list);
|
return PyModule_Add(m, "_have_functions", list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,51 +73,20 @@ module time
|
||||||
static int
|
static int
|
||||||
check_ticks_per_second(long tps, const char *context)
|
check_ticks_per_second(long tps, const char *context)
|
||||||
{
|
{
|
||||||
/* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
|
/* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, tps)
|
||||||
cannot overflow. */
|
cannot overflow. */
|
||||||
if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) {
|
if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) {
|
||||||
PyErr_Format(PyExc_OverflowError, "%s is too large", context);
|
PyErr_Format(PyExc_OverflowError, "%s is too large", context);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (tps < 1) {
|
||||||
|
PyErr_Format(PyExc_RuntimeError, "invalid %s", context);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TIMES || HAVE_CLOCK */
|
#endif /* HAVE_TIMES || HAVE_CLOCK */
|
||||||
|
|
||||||
#ifdef HAVE_TIMES
|
|
||||||
|
|
||||||
# define ticks_per_second _PyRuntime.time.ticks_per_second
|
|
||||||
|
|
||||||
static void
|
|
||||||
ensure_ticks_per_second(void)
|
|
||||||
{
|
|
||||||
if (_PyRuntime.time.ticks_per_second_initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_PyRuntime.time.ticks_per_second_initialized = 1;
|
|
||||||
# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
|
|
||||||
ticks_per_second = sysconf(_SC_CLK_TCK);
|
|
||||||
if (ticks_per_second < 1) {
|
|
||||||
ticks_per_second = -1;
|
|
||||||
}
|
|
||||||
# elif defined(HZ)
|
|
||||||
ticks_per_second = HZ;
|
|
||||||
# else
|
|
||||||
ticks_per_second = 60; /* magic fallback value; may be bogus */
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_TIMES */
|
|
||||||
|
|
||||||
|
|
||||||
PyStatus
|
|
||||||
_PyTime_Init(void)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_TIMES
|
|
||||||
ensure_ticks_per_second();
|
|
||||||
#endif
|
|
||||||
return PyStatus_Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static int pysleep(_PyTime_t timeout);
|
static int pysleep(_PyTime_t timeout);
|
||||||
|
@ -125,6 +94,14 @@ static int pysleep(_PyTime_t timeout);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyTypeObject *struct_time_type;
|
PyTypeObject *struct_time_type;
|
||||||
|
#ifdef HAVE_TIMES
|
||||||
|
// times() clock frequency in hertz
|
||||||
|
long ticks_per_second;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CLOCK
|
||||||
|
// clock() frequency in hertz
|
||||||
|
long clocks_per_second;
|
||||||
|
#endif
|
||||||
} time_module_state;
|
} time_module_state;
|
||||||
|
|
||||||
static inline time_module_state*
|
static inline time_module_state*
|
||||||
|
@ -184,7 +161,7 @@ PyDoc_STRVAR(time_ns_doc,
|
||||||
\n\
|
\n\
|
||||||
Return the current time in nanoseconds since the Epoch.");
|
Return the current time in nanoseconds since the Epoch.");
|
||||||
|
|
||||||
#if defined(HAVE_CLOCK)
|
#ifdef HAVE_CLOCK
|
||||||
|
|
||||||
#ifndef CLOCKS_PER_SEC
|
#ifndef CLOCKS_PER_SEC
|
||||||
# ifdef CLK_TCK
|
# ifdef CLK_TCK
|
||||||
|
@ -195,15 +172,12 @@ Return the current time in nanoseconds since the Epoch.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
py_clock(time_module_state *state, _PyTime_t *tp, _Py_clock_info_t *info)
|
||||||
{
|
{
|
||||||
if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) {
|
long clocks_per_second = state->clocks_per_second;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
info->implementation = "clock()";
|
info->implementation = "clock()";
|
||||||
info->resolution = 1.0 / (double)CLOCKS_PER_SEC;
|
info->resolution = 1.0 / (double)clocks_per_second;
|
||||||
info->monotonic = 1;
|
info->monotonic = 1;
|
||||||
info->adjustable = 0;
|
info->adjustable = 0;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +189,7 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
||||||
"or its value cannot be represented");
|
"or its value cannot be represented");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
|
_PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, clocks_per_second);
|
||||||
*tp = _PyTime_FromNanoseconds(ns);
|
*tp = _PyTime_FromNanoseconds(ns);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1277,8 +1251,38 @@ PyDoc_STRVAR(perf_counter_ns_doc,
|
||||||
\n\
|
\n\
|
||||||
Performance counter for benchmarking as nanoseconds.");
|
Performance counter for benchmarking as nanoseconds.");
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMES
|
||||||
static int
|
static int
|
||||||
_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
process_time_times(time_module_state *state, _PyTime_t *tp,
|
||||||
|
_Py_clock_info_t *info)
|
||||||
|
{
|
||||||
|
long ticks_per_second = state->ticks_per_second;
|
||||||
|
|
||||||
|
struct tms process;
|
||||||
|
if (times(&process) == (clock_t)-1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
info->implementation = "times()";
|
||||||
|
info->monotonic = 1;
|
||||||
|
info->adjustable = 0;
|
||||||
|
info->resolution = 1.0 / (double)ticks_per_second;
|
||||||
|
}
|
||||||
|
|
||||||
|
_PyTime_t ns;
|
||||||
|
ns = _PyTime_MulDiv(process.tms_utime, SEC_TO_NS, ticks_per_second);
|
||||||
|
ns += _PyTime_MulDiv(process.tms_stime, SEC_TO_NS, ticks_per_second);
|
||||||
|
*tp = _PyTime_FromNanoseconds(ns);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
py_process_time(time_module_state *state, _PyTime_t *tp,
|
||||||
|
_Py_clock_info_t *info)
|
||||||
{
|
{
|
||||||
#if defined(MS_WINDOWS)
|
#if defined(MS_WINDOWS)
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
|
@ -1381,41 +1385,28 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
||||||
|
|
||||||
/* times() */
|
/* times() */
|
||||||
#ifdef HAVE_TIMES
|
#ifdef HAVE_TIMES
|
||||||
struct tms t;
|
int res = process_time_times(state, tp, info);
|
||||||
|
if (res < 0) {
|
||||||
if (times(&t) != (clock_t)-1) {
|
return -1;
|
||||||
assert(_PyRuntime.time.ticks_per_second_initialized);
|
|
||||||
if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ticks_per_second != -1) {
|
|
||||||
if (info) {
|
|
||||||
info->implementation = "times()";
|
|
||||||
info->monotonic = 1;
|
|
||||||
info->adjustable = 0;
|
|
||||||
info->resolution = 1.0 / (double)ticks_per_second;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyTime_t ns;
|
|
||||||
ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
|
|
||||||
ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
|
|
||||||
*tp = _PyTime_FromNanoseconds(ns);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (res == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// times() failed, ignore failure
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* clock */
|
/* clock */
|
||||||
/* Currently, Python 3 requires clock() to build: see issue #22624 */
|
/* Currently, Python 3 requires clock() to build: see issue #22624 */
|
||||||
return _PyTime_GetClockWithInfo(tp, info);
|
return py_clock(state, tp, info);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
time_process_time(PyObject *self, PyObject *unused)
|
time_process_time(PyObject *module, PyObject *unused)
|
||||||
{
|
{
|
||||||
|
time_module_state *state = get_time_state(module);
|
||||||
_PyTime_t t;
|
_PyTime_t t;
|
||||||
if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
|
if (py_process_time(state, &t, NULL) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return _PyFloat_FromPyTime(t);
|
return _PyFloat_FromPyTime(t);
|
||||||
|
@ -1427,10 +1418,11 @@ PyDoc_STRVAR(process_time_doc,
|
||||||
Process time for profiling: sum of the kernel and user-space CPU time.");
|
Process time for profiling: sum of the kernel and user-space CPU time.");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
time_process_time_ns(PyObject *self, PyObject *unused)
|
time_process_time_ns(PyObject *module, PyObject *unused)
|
||||||
{
|
{
|
||||||
|
time_module_state *state = get_time_state(module);
|
||||||
_PyTime_t t;
|
_PyTime_t t;
|
||||||
if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
|
if (py_process_time(state, &t, NULL) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return _PyTime_AsNanosecondsObject(t);
|
return _PyTime_AsNanosecondsObject(t);
|
||||||
|
@ -1617,7 +1609,7 @@ sum of the kernel and user-space CPU time.");
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
time_get_clock_info(PyObject *self, PyObject *args)
|
time_get_clock_info(PyObject *module, PyObject *args)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
_Py_clock_info_t info;
|
_Py_clock_info_t info;
|
||||||
|
@ -1656,7 +1648,8 @@ time_get_clock_info(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(name, "process_time") == 0) {
|
else if (strcmp(name, "process_time") == 0) {
|
||||||
if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) {
|
time_module_state *state = get_time_state(module);
|
||||||
|
if (py_process_time(state, &t, &info) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2116,6 +2109,25 @@ time_exec(PyObject *module)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMES
|
||||||
|
if (_Py_GetTicksPerSecond(&state->ticks_per_second) < 0) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"cannot read ticks_per_second");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_ticks_per_second(state->ticks_per_second, "_SC_CLK_TCK") < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CLOCK
|
||||||
|
state->clocks_per_second = CLOCKS_PER_SEC;
|
||||||
|
if (check_ticks_per_second(state->clocks_per_second, "CLOCKS_PER_SEC") < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2943,3 +2943,27 @@ _Py_closerange(int first, int last)
|
||||||
#endif /* USE_FDWALK */
|
#endif /* USE_FDWALK */
|
||||||
_Py_END_SUPPRESS_IPH
|
_Py_END_SUPPRESS_IPH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
// Ticks per second used by clock() and times() functions.
|
||||||
|
// See os.times() and time.process_time() implementations.
|
||||||
|
int
|
||||||
|
_Py_GetTicksPerSecond(long *ticks_per_second)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
|
||||||
|
long value = sysconf(_SC_CLK_TCK);
|
||||||
|
if (value < 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ticks_per_second = value;
|
||||||
|
#elif defined(HZ)
|
||||||
|
assert(HZ >= 1);
|
||||||
|
*ticks_per_second = HZ;
|
||||||
|
#else
|
||||||
|
// Magic fallback value; may be bogus
|
||||||
|
*ticks_per_second = 60;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -528,11 +528,6 @@ pycore_init_runtime(_PyRuntimeState *runtime,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _PyTime_Init();
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _PyImport_Init();
|
status = _PyImport_Init();
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue