From 4c0d046f3cb0a1d57de58f334c83f767d48e67ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 16 Nov 2023 00:38:37 +0100 Subject: [PATCH] gh-110850: Add PyTime_t C API Add PyTime_t API: * PyTime_t type. * PyTime_MIN and PyTime_MAX constants. * PyTime_AsSecondsDouble(), PyTime_GetMonotonicClock(), PyTime_GetPerfCounter() and PyTime_GetSystemClock() functions. --- Doc/c-api/time.rst | 132 ++++++++++++++++++++++++++ Doc/c-api/utilities.rst | 1 + Doc/whatsnew/3.13.rst | 10 ++ Include/Python.h | 1 + Include/cpython/pytime.h | 23 +++++ Include/internal/pycore_time.h | 100 ++----------------- Lib/test/test_time.py | 14 +-- Modules/_datetimemodule.c | 2 +- Modules/_lsprof.c | 6 +- Modules/_randommodule.c | 6 +- Modules/_testinternalcapi/pytime.c | 6 +- Modules/_testinternalcapi/test_lock.c | 4 +- Modules/_testsinglephase.c | 4 +- Modules/_threadmodule.c | 2 +- Modules/gcmodule.c | 6 +- Modules/socketmodule.c | 4 +- Modules/timemodule.c | 12 +-- Python/import.c | 6 +- Python/lock.c | 4 +- Python/parking_lot.c | 10 +- Python/pytime.c | 76 +++++++-------- Python/thread_nt.h | 10 +- Python/thread_pthread.h | 21 ++-- 23 files changed, 270 insertions(+), 190 deletions(-) create mode 100644 Doc/c-api/time.rst create mode 100644 Include/cpython/pytime.h diff --git a/Doc/c-api/time.rst b/Doc/c-api/time.rst new file mode 100644 index 000000000000000..b4270575fbb27fb --- /dev/null +++ b/Doc/c-api/time.rst @@ -0,0 +1,132 @@ +.. highlight:: c + +PyTime API +========== + +.. versionadded:: 3.13 + +PyTime API +---------- + +The PyTime_t API is written to use timestamp and timeout values stored in +various formats and to read clocks. + +The :c:type:`PyTime_t` type is an integer to support directly common arithmetic +operations such as ``t1 + t2``. + +The PyTime_t API supports a resolution of ``1`` nanosecond. The +:c:type:`PyTime_t` type is signed to support negative timestamps. The supported +range is around [-292.3 years; +292.3 years]. Using the Unix epoch (January +1st, 1970), the supported date range is around [1677-09-21; 2262-04-11]. + +Time formats: + +* Seconds. +* Seconds as a floating pointer number (C :c:type:`double`). +* Milliseconds (10\ :sup:`-3` seconds). +* Microseconds (10\ :sup:`-6` seconds). +* 100 nanoseconds (10\ :sup:`-7` seconds), used on Windows. +* Nanoseconds (10\ :sup:`-9` seconds). +* :c:expr:`timeval` structure, 1 microsecond (10\ :sup:`-6` seconds). +* :c:expr:`timespec` structure, 1 nanosecond (10\ :sup:`-9` seconds). + +Integer overflows are detected and raise :exc:`OverflowError`. Conversion to a +resolution larger than 1 nanosecond is rounded correctly with the requested +rounding mode. Available rounding modes: + +* Round towards minus infinity (-inf). For example, used to read a clock. +* Round towards infinity (+inf). For example, used for timeout to wait "at + least" N seconds. +* Round to nearest with ties going to nearest even integer. For example, used + to round from a Python float. +* Round away from zero. For example, used for timeout. + +Some functions clamp the result in the range [PyTime_MIN; PyTime_MAX]. The +caller doesn't have to handle errors and so doesn't need to hold the GIL to +handle exceptions. For example, ``_PyTime_Add(t1, t2)`` computes ``t1+t2`` and +clamps the result on overflow. + +Clocks: + +* System clock +* Monotonic clock +* Performance counter + +Internally, operations like ``(t * k / q)`` with integers are implemented in a +way to reduce the risk of integer overflow. Such operation is used to convert a +clock value expressed in ticks with a frequency to PyTime_t, like +``QueryPerformanceCounter()`` with ``QueryPerformanceFrequency()`` on Windows. + + +Types +----- + +.. c:type:: PyTime_t + + Timestamp type with subsecond precision: 64-bit signed integer. + + This type can be used to store a duration. Indirectly, it can be used to + store a date relative to a reference date, such as the UNIX epoch. + + +Constants +--------- + +.. c:var:: PyTime_t PyTime_MIN + + Minimum value of the :c:type:`PyTime_t` type. + :c:macro`PyTime_MIN` nanoseconds is around -292.3 years. + +.. c:var:: PyTime_t PyTime_MAX + + Maximum value of the :c:type:`PyTime_t` type. + :c:macro`PyTime_MAX` nanoseconds is around +292.3 years. + + +Functions +--------- + +.. c:function:: double PyTime_AsSecondsDouble(PyTime_t t) + + Convert a timestamp to a number of seconds as a C :c:type:`double`. + + The function cannot fail. + + +.. c:function:: PyTime_t PyTime_GetMonotonicClock(void) + + Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + If reading the clock fails, silently ignore the error and return 0. + + On integer overflow, silently ignore the overflow and clamp the clock to + the [PyTime_MIN; PyTime_MAX] range. + + See also the :func:`time.monotonic` function. + +.. c:function:: PyTime_t PyTime_GetPerfCounter(void) + + Get the performance counter: clock with the highest available resolution to + measure a short duration. + + If reading the clock fails, silently ignore the error and return 0. + + On integer overflow, silently ignore the overflow and clamp the time to the + [PyTime_MIN; PyTime_MAX] range. + + See also the :func:`time.perf_counter` function. + + +.. c:function:: PyTime_t PyTime_GetSystemClock(void) + + Get the current time from the system clock. + + If reading the clock fails, silently ignore the error and return ``0``. + + On integer overflow, silently ignore the overflow and clamp the clock to + the [PyTime_MIN; PyTime_MAX] range. + + See also the :func:`time.time` function. diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst index 48ae54acebe8879..9d0abf440f791d4 100644 --- a/Doc/c-api/utilities.rst +++ b/Doc/c-api/utilities.rst @@ -20,4 +20,5 @@ and parsing function arguments and constructing Python values from C values. hash.rst reflection.rst codec.rst + time.rst perfmaps.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index b64cfc51f75701b..b7bb971ef2ea5c7 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1181,6 +1181,16 @@ New Features :exc:`KeyError` if the key missing. (Contributed by Stefan Behnel and Victor Stinner in :gh:`111262`.) +* Add PyTime_t C API: + + * :c:type:`PyTime_t` type. + * :c:var:`PyTime_MIN` and :c:var:`PyTime_MAX` constants. + * :c:func:`PyTime_AsSecondsDouble`, :c:func:`PyTime_GetMonotonicClock`, + :c:func:`PyTime_GetPerfCounter` and :c:func:`PyTime_GetSystemClock` + functions. + + (Contributed by Victor Stinner in :gh:`110850`.) + Porting to Python 3.13 ---------------------- diff --git a/Include/Python.h b/Include/Python.h index 196751c3201e620..01fc45137a17bbc 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -97,6 +97,7 @@ #include "weakrefobject.h" #include "structseq.h" #include "cpython/picklebufobject.h" +#include "cpython/pytime.h" #include "codecs.h" #include "pyerrors.h" #include "pythread.h" diff --git a/Include/cpython/pytime.h b/Include/cpython/pytime.h new file mode 100644 index 000000000000000..891988198f67ee6 --- /dev/null +++ b/Include/cpython/pytime.h @@ -0,0 +1,23 @@ +// PyTime_t C API: see Doc/c-api/time.rst for the documentation. + +#ifndef Py_LIMITED_API +#ifndef Py_PYTIME_H +#define Py_PYTIME_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef int64_t PyTime_t; +#define PyTime_MIN INT64_MIN +#define PyTime_MAX INT64_MAX + +PyAPI_FUNC(double) PyTime_AsSecondsDouble(PyTime_t t); +PyAPI_FUNC(PyTime_t) PyTime_GetMonotonicClock(void); +PyAPI_FUNC(PyTime_t) PyTime_GetPerfCounter(void); +PyAPI_FUNC(PyTime_t) PyTime_GetSystemClock(void); + +#ifdef __cplusplus +} +#endif +#endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/internal/pycore_time.h b/Include/internal/pycore_time.h index 46713f91d190ffc..4ecf97ffac7c249 100644 --- a/Include/internal/pycore_time.h +++ b/Include/internal/pycore_time.h @@ -1,45 +1,4 @@ -// The _PyTime_t API is written to use timestamp and timeout values stored in -// various formats and to read clocks. -// -// The _PyTime_t type is an integer to support directly common arithmetic -// operations like t1 + t2. -// -// The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type -// is signed to support negative timestamps. The supported range is around -// [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the -// supported date range is around [1677-09-21; 2262-04-11]. -// -// Formats: -// -// * seconds -// * seconds as a floating pointer number (C double) -// * milliseconds (10^-3 seconds) -// * microseconds (10^-6 seconds) -// * 100 nanoseconds (10^-7 seconds) -// * nanoseconds (10^-9 seconds) -// * timeval structure, 1 microsecond resolution (10^-6 seconds) -// * timespec structure, 1 nanosecond resolution (10^-9 seconds) -// -// Integer overflows are detected and raise OverflowError. Conversion to a -// resolution worse than 1 nanosecond is rounded correctly with the requested -// rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling -// (towards +inf), half even and up (away from zero). -// -// Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so -// the caller doesn't have to handle errors and doesn't need to hold the GIL. -// For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on -// overflow. -// -// Clocks: -// -// * System clock -// * Monotonic clock -// * Performance counter -// -// Operations like (t * k / q) with integers are implemented in a way to reduce -// the risk of integer overflow. Such operation is used to convert a clock -// value expressed in ticks with a frequency to _PyTime_t, like -// QueryPerformanceCounter() with QueryPerformanceFrequency(). +// Internal PyTime_t C API: see Doc/c-api/time.rst for the documentation. #ifndef Py_INTERNAL_TIME_H #define Py_INTERNAL_TIME_H @@ -66,14 +25,7 @@ struct _time_runtime_state { struct timeval; #endif -// _PyTime_t: Python timestamp with subsecond precision. It can be used to -// store a duration, and so indirectly a date (related to another date, like -// UNIX epoch). -typedef int64_t _PyTime_t; -// _PyTime_MIN nanoseconds is around -292.3 years -#define _PyTime_MIN INT64_MIN -// _PyTime_MAX nanoseconds is around +292.3 years -#define _PyTime_MAX INT64_MAX +typedef PyTime_t _PyTime_t; #define _SIZEOF_PYTIME_T 8 typedef enum { @@ -157,7 +109,7 @@ PyAPI_FUNC(_PyTime_t) _PyTime_FromSecondsDouble(double seconds, _PyTime_round_t PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); // Create a timestamp from a number of microseconds. -// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Clamp to [PyTime_MIN; PyTime_MAX] on overflow. extern _PyTime_t _PyTime_FromMicrosecondsClamp(_PyTime_t us); // Create a timestamp from nanoseconds (Python int). @@ -179,10 +131,6 @@ PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round); -// Convert a timestamp to a number of seconds as a C double. -// Export for '_socket' shared extension. -PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); - // Convert timestamp to a number of milliseconds (10^-3 seconds). // Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, @@ -260,11 +208,11 @@ PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts); #endif -// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Compute t1 + t2. Clamp to [PyTime_MIN; PyTime_MAX] on overflow. extern _PyTime_t _PyTime_Add(_PyTime_t t1, _PyTime_t t2); // Compute ticks * mul / div. -// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Clamp to [PyTime_MIN; PyTime_MAX] on overflow. // The caller must ensure that ((div - 1) * mul) cannot overflow. extern _PyTime_t _PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, @@ -278,16 +226,6 @@ typedef struct { double resolution; } _Py_clock_info_t; -// Get the current time from the system clock. -// -// If the internal clock fails, silently ignore the error and return 0. -// On integer overflow, silently ignore the overflow and clamp the clock to -// [_PyTime_MIN; _PyTime_MAX]. -// -// Use _PyTime_GetSystemClockWithInfo() to check for failure. -// Export for '_random' shared extension. -PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); - // Get the current time from the system clock. // On success, set *t and *info (if not NULL), and return 0. // On error, raise an exception and return -1. @@ -295,19 +233,6 @@ extern int _PyTime_GetSystemClockWithInfo( _PyTime_t *t, _Py_clock_info_t *info); -// Get the time of a monotonic clock, i.e. a clock that cannot go backwards. -// The clock is not affected by system clock updates. The reference point of -// the returned value is undefined, so that only the difference between the -// results of consecutive calls is valid. -// -// If the internal clock fails, silently ignore the error and return 0. -// On integer overflow, silently ignore the overflow and clamp the clock to -// [_PyTime_MIN; _PyTime_MAX]. -// -// Use _PyTime_GetMonotonicClockWithInfo() to check for failure. -// Export for '_random' shared extension. -PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); - // Get the time of a monotonic clock, i.e. a clock that cannot go backwards. // The clock is not affected by system clock updates. The reference point of // the returned value is undefined, so that only the difference between the @@ -332,17 +257,6 @@ PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); // Export for '_datetime' shared extension. PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); -// Get the performance counter: clock with the highest available resolution to -// measure a short duration. -// -// If the internal clock fails, silently ignore the error and return 0. -// On integer overflow, silently ignore the overflow and clamp the clock to -// [_PyTime_MIN; _PyTime_MAX]. -// -// Use _PyTime_GetPerfCounterWithInfo() to check for failure. -// Export for '_lsprof' shared extension. -PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); - // Get the performance counter: clock with the highest available resolution to // measure a short duration. // @@ -355,12 +269,12 @@ extern int _PyTime_GetPerfCounterWithInfo( // Create a deadline. -// Pseudo code: _PyTime_GetMonotonicClock() + timeout. +// Pseudo code: PyTime_GetMonotonicClock() + timeout. // Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout); // Get remaining time from a deadline. -// Pseudo code: deadline - _PyTime_GetMonotonicClock(). +// Pseudo code: deadline - PyTime_GetMonotonicClock(). // Export for '_ssl' shared extension. PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline); diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 3b5640abdb6b892..1b5691c6655dd5d 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -43,8 +43,8 @@ class _PyTime(enum.IntEnum): ROUND_UP = 3 # _PyTime_t is int64_t -_PyTime_MIN = -2 ** 63 -_PyTime_MAX = 2 ** 63 - 1 +PyTime_MIN = -2 ** 63 +PyTime_MAX = 2 ** 63 - 1 # Rounding modes supported by PyTime ROUNDING_MODES = ( @@ -934,7 +934,7 @@ def test_FromSecondsObject(self): _PyTime_FromSecondsObject(float('nan'), time_rnd) def test_AsSecondsDouble(self): - from _testinternalcapi import _PyTime_AsSecondsDouble + from _testinternalcapi import PyTime_AsSecondsDouble def float_converter(ns): if abs(ns) % SEC_TO_NS == 0: @@ -942,14 +942,14 @@ def float_converter(ns): else: return float(ns) / SEC_TO_NS - self.check_int_rounding(lambda ns, rnd: _PyTime_AsSecondsDouble(ns), + self.check_int_rounding(lambda ns, rnd: PyTime_AsSecondsDouble(ns), float_converter, NS_TO_SEC) # test nan for time_rnd, _ in ROUNDING_MODES: with self.assertRaises(TypeError): - _PyTime_AsSecondsDouble(float('nan')) + PyTime_AsSecondsDouble(float('nan')) def create_decimal_converter(self, denominator): denom = decimal.Decimal(denominator) @@ -1009,7 +1009,7 @@ def test_AsTimeval_clamp(self): tv_sec_max = self.time_t_max tv_sec_min = self.time_t_min - for t in (_PyTime_MIN, _PyTime_MAX): + for t in (PyTime_MIN, PyTime_MAX): ts = _PyTime_AsTimeval_clamp(t, _PyTime.ROUND_CEILING) with decimal.localcontext() as context: context.rounding = decimal.ROUND_CEILING @@ -1028,7 +1028,7 @@ def test_AsTimeval_clamp(self): def test_AsTimespec_clamp(self): from _testinternalcapi import _PyTime_AsTimespec_clamp - for t in (_PyTime_MIN, _PyTime_MAX): + for t in (PyTime_MIN, PyTime_MAX): ts = _PyTime_AsTimespec_clamp(t) tv_sec, tv_nsec = divmod(t, NS_TO_SEC) if self.time_t_max < tv_sec: diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index cb5403e8461ff0e..fa8a198ec712914 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -5098,7 +5098,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, static PyObject * datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) { - _PyTime_t ts = _PyTime_GetSystemClock(); + PyTime_t ts = PyTime_GetSystemClock(); time_t secs; int us; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 8f09204097529f4..c7d0796b2356131 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -84,7 +84,7 @@ _lsprof_get_state(PyObject *module) /*** External Timers ***/ -static _PyTime_t CallExternalTimer(ProfilerObject *pObj) +static PyTime_t CallExternalTimer(ProfilerObject *pObj) { PyObject *o = _PyObject_CallNoArgs(pObj->externalTimer); if (o == NULL) { @@ -113,14 +113,14 @@ static _PyTime_t CallExternalTimer(ProfilerObject *pObj) return result; } -static inline _PyTime_t +static inline PyTime_t call_timer(ProfilerObject *pObj) { if (pObj->externalTimer != NULL) { return CallExternalTimer(pObj); } else { - return _PyTime_GetPerfCounter(); + return PyTime_GetPerfCounter(); } } diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 514bec16a347f4b..26c19fe899a96a2 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -261,10 +261,10 @@ random_seed_urandom(RandomObject *self) static void random_seed_time_pid(RandomObject *self) { - _PyTime_t now; + PyTime_t now; uint32_t key[5]; - now = _PyTime_GetSystemClock(); + now = PyTime_GetSystemClock(); key[0] = (uint32_t)(now & 0xffffffffU); key[1] = (uint32_t)(now >> 32); @@ -276,7 +276,7 @@ random_seed_time_pid(RandomObject *self) key[2] = 0; #endif - now = _PyTime_GetMonotonicClock(); + now = PyTime_GetMonotonicClock(); key[3] = (uint32_t)(now & 0xffffffffU); key[4] = (uint32_t)(now >> 32); diff --git a/Modules/_testinternalcapi/pytime.c b/Modules/_testinternalcapi/pytime.c index 2b5f9eb0ef28511..26d76e6fe441d61 100644 --- a/Modules/_testinternalcapi/pytime.c +++ b/Modules/_testinternalcapi/pytime.c @@ -59,11 +59,11 @@ test_pytime_assecondsdouble(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O", &obj)) { return NULL; } - _PyTime_t ts; + PyTime_t ts; if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { return NULL; } - double d = _PyTime_AsSecondsDouble(ts); + double d = PyTime_AsSecondsDouble(ts); return PyFloat_FromDouble(d); } @@ -254,7 +254,7 @@ test_pytime_object_to_timespec(PyObject *self, PyObject *args) static PyMethodDef TestMethods[] = { {"_PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, {"_PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, - {"_PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, + {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, #ifdef HAVE_CLOCK_GETTIME {"_PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, {"_PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, diff --git a/Modules/_testinternalcapi/test_lock.c b/Modules/_testinternalcapi/test_lock.c index 82a0c827deeddf9..fd70becd3e0f25a 100644 --- a/Modules/_testinternalcapi/test_lock.c +++ b/Modules/_testinternalcapi/test_lock.c @@ -289,7 +289,7 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module, goto exit; } - _PyTime_t start = _PyTime_GetMonotonicClock(); + _PyTime_t start = PyTime_GetMonotonicClock(); for (Py_ssize_t i = 0; i < num_threads; i++) { thread_data[i].bench_data = &bench_data; @@ -306,7 +306,7 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module, } Py_ssize_t total_iters = bench_data.total_iters; - _PyTime_t end = _PyTime_GetMonotonicClock(); + PyTime_t end = PyTime_GetMonotonicClock(); // Return the total number of acquisitions and the number of acquisitions // for each thread. diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c index c42a15a0eff4944..7f8e591dbbf100b 100644 --- a/Modules/_testsinglephase.c +++ b/Modules/_testsinglephase.c @@ -136,7 +136,7 @@ init_module(PyObject *module, module_state *state) return -1; } - double d = _PyTime_AsSecondsDouble(state->initialized); + double d = PyTime_AsSecondsDouble(state->initialized); if (PyModule_Add(module, "_module_initialized", PyFloat_FromDouble(d)) < 0) { return -1; } @@ -157,7 +157,7 @@ common_state_initialized(PyObject *self, PyObject *Py_UNUSED(ignored)) if (state == NULL) { Py_RETURN_NONE; } - double d = _PyTime_AsSecondsDouble(state->initialized); + double d = PyTime_AsSecondsDouble(state->initialized); return PyFloat_FromDouble(d); } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index c608789b5fbd5c8..c99b49f542bb5fd 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1890,7 +1890,7 @@ thread_module_exec(PyObject *module) // TIMEOUT_MAX double timeout_max = (double)PY_TIMEOUT_MAX * 1e-6; - double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); + double time_max = PyTime_AsSecondsDouble(PyTime_MAX); timeout_max = Py_MIN(timeout_max, time_max); // Round towards minus infinity timeout_max = floor(timeout_max); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 568e02a4210a2b2..acf301689894543 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1213,7 +1213,7 @@ gc_collect_main(PyThreadState *tstate, int generation, PyGC_Head unreachable; /* non-problematic unreachable trash */ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; - _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ + PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ GCState *gcstate = &tstate->interp->gc; // gc_collect_main() must not be called before _PyGC_Init @@ -1224,7 +1224,7 @@ gc_collect_main(PyThreadState *tstate, int generation, if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); show_stats_each_generations(gcstate); - t1 = _PyTime_GetPerfCounter(); + t1 = PyTime_GetPerfCounter(); } if (PyDTrace_GC_START_ENABLED()) @@ -1320,7 +1320,7 @@ gc_collect_main(PyThreadState *tstate, int generation, debug_cycle("uncollectable", FROM_GC(gc)); } if (gcstate->debug & DEBUG_STATS) { - double d = _PyTime_AsSecondsDouble(_PyTime_GetPerfCounter() - t1); + double d = PyTime_AsSecondsDouble(PyTime_GetPerfCounter() - t1); PySys_WriteStderr( "gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n", n+m, n, d); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 9ac2001c0132d35..507e9a0f96d7837 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3112,7 +3112,7 @@ sock_gettimeout(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } else { - double seconds = _PyTime_AsSecondsDouble(s->sock_timeout); + double seconds = PyTime_AsSecondsDouble(s->sock_timeout); return PyFloat_FromDouble(seconds); } } @@ -6916,7 +6916,7 @@ socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } else { - double seconds = _PyTime_AsSecondsDouble(state->defaulttimeout); + double seconds = PyTime_AsSecondsDouble(state->defaulttimeout); return PyFloat_FromDouble(seconds); } } diff --git a/Modules/timemodule.c b/Modules/timemodule.c index e82f6eb98ebaf35..2f26477de3f2fd1 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -75,7 +75,7 @@ check_ticks_per_second(long tps, const char *context) { /* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) 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); return -1; } @@ -137,9 +137,9 @@ get_time_state(PyObject *module) static PyObject* -_PyFloat_FromPyTime(_PyTime_t t) +_PyFloat_FromPyTime(PyTime_t t) { - double d = _PyTime_AsSecondsDouble(t); + double d = PyTime_AsSecondsDouble(t); return PyFloat_FromDouble(d); } @@ -147,7 +147,7 @@ _PyFloat_FromPyTime(_PyTime_t t) static int get_system_time(_PyTime_t *t) { - // Avoid _PyTime_GetSystemClock() which silently ignores errors. + // Avoid PyTime_GetSystemClock() which silently ignores errors. return _PyTime_GetSystemClockWithInfo(t, NULL); } @@ -1202,7 +1202,7 @@ should not be relied on."); static int get_monotonic(_PyTime_t *t) { - // Avoid _PyTime_GetMonotonicClock() which silently ignores errors. + // Avoid PyTime_GetMonotonicClock() which silently ignores errors. return _PyTime_GetMonotonicClockWithInfo(t, NULL); } @@ -1241,7 +1241,7 @@ Monotonic clock, cannot go backward, as nanoseconds."); static int get_perf_counter(_PyTime_t *t) { - // Avoid _PyTime_GetPerfCounter() which silently ignores errors. + // Avoid PyTime_GetPerfCounter() which silently ignores errors. return _PyTime_GetPerfCounterWithInfo(t, NULL); } diff --git a/Python/import.c b/Python/import.c index f37393bbdc42695..26d8fbf29c5df05 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2720,7 +2720,7 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) #define import_level FIND_AND_LOAD(interp).import_level #define accumulated FIND_AND_LOAD(interp).accumulated - _PyTime_t t1 = 0, accumulated_copy = accumulated; + PyTime_t t1 = 0, accumulated_copy = accumulated; PyObject *sys_path = PySys_GetObject("path"); PyObject *sys_meta_path = PySys_GetObject("meta_path"); @@ -2748,7 +2748,7 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) #undef header import_level++; - t1 = _PyTime_GetPerfCounter(); + t1 = PyTime_GetPerfCounter(); accumulated = 0; } @@ -2763,7 +2763,7 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) mod != NULL); if (import_time) { - _PyTime_t cum = _PyTime_GetPerfCounter() - t1; + PyTime_t cum = PyTime_GetPerfCounter() - t1; import_level--; fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", diff --git a/Python/lock.c b/Python/lock.c index 3dad2aa93b5cc97..f1af7b29e84f818 100644 --- a/Python/lock.c +++ b/Python/lock.c @@ -65,7 +65,7 @@ _PyMutex_LockTimed(PyMutex *m, _PyTime_t timeout, _PyLockFlags flags) return PY_LOCK_FAILURE; } - _PyTime_t now = _PyTime_GetMonotonicClock(); + _PyTime_t now = PyTime_GetMonotonicClock(); _PyTime_t endtime = 0; if (timeout > 0) { endtime = _PyTime_Add(now, timeout); @@ -142,7 +142,7 @@ mutex_unpark(PyMutex *m, struct mutex_entry *entry, int has_more_waiters) { uint8_t v = 0; if (entry) { - _PyTime_t now = _PyTime_GetMonotonicClock(); + PyTime_t now = PyTime_GetMonotonicClock(); int should_be_fair = now > entry->time_to_be_fair; entry->handed_off = should_be_fair; diff --git a/Python/parking_lot.c b/Python/parking_lot.c index 664e622cc174741..ba167941e65002a 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -91,7 +91,7 @@ _PySemaphore_Destroy(_PySemaphore *sema) } static int -_PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) +_PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout) { int res; #if defined(MS_WINDOWS) @@ -118,7 +118,7 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) if (timeout >= 0) { struct timespec ts; - _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); + PyTime_t deadline = _PyTime_Add(PyTime_GetSystemClock(), timeout); _PyTime_AsTimespec(deadline, &ts); err = sem_timedwait(&sema->platform_sem, &ts); @@ -150,7 +150,7 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) if (timeout >= 0) { struct timespec ts; - _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); + PyTime_t deadline = _PyTime_Add(PyTime_GetSystemClock(), timeout); _PyTime_AsTimespec(deadline, &ts); err = pthread_cond_timedwait(&sema->cond, &sema->mutex, &ts); @@ -175,7 +175,7 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) } int -_PySemaphore_Wait(_PySemaphore *sema, _PyTime_t timeout, int detach) +_PySemaphore_Wait(_PySemaphore *sema, PyTime_t timeout, int detach) { PyThreadState *tstate = NULL; if (detach) { @@ -268,7 +268,7 @@ atomic_memcmp(const void *addr, const void *expected, size_t addr_size) int _PyParkingLot_Park(const void *addr, const void *expected, size_t size, - _PyTime_t timeout_ns, void *park_arg, int detach) + PyTime_t timeout_ns, void *park_arg, int detach) { struct wait_entry wait = { .park_arg = park_arg, diff --git a/Python/pytime.c b/Python/pytime.c index e4813d4a9c2a2ad..0f615d324491ce8 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -50,7 +50,7 @@ # error "time_t is not a two's complement integer type" #endif -#if _PyTime_MIN + _PyTime_MAX != -1 +#if PyTime_MIN + PyTime_MAX != -1 # error "_PyTime_t is not a two's complement integer type" #endif @@ -87,16 +87,16 @@ pytime_as_nanoseconds(_PyTime_t t) } -// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Compute t1 + t2. Clamp to [PyTime_MIN; PyTime_MAX] on overflow. static inline int pytime_add(_PyTime_t *t1, _PyTime_t t2) { - if (t2 > 0 && *t1 > _PyTime_MAX - t2) { - *t1 = _PyTime_MAX; + if (t2 > 0 && *t1 > PyTime_MAX - t2) { + *t1 = PyTime_MAX; return -1; } - else if (t2 < 0 && *t1 < _PyTime_MIN - t2) { - *t1 = _PyTime_MIN; + else if (t2 < 0 && *t1 < PyTime_MIN - t2) { + *t1 = PyTime_MIN; return -1; } else { @@ -119,7 +119,7 @@ pytime_mul_check_overflow(_PyTime_t a, _PyTime_t b) { if (b != 0) { assert(b > 0); - return ((a < _PyTime_MIN / b) || (_PyTime_MAX / b < a)); + return ((a < PyTime_MIN / b) || (PyTime_MAX / b < a)); } else { return 0; @@ -127,13 +127,13 @@ pytime_mul_check_overflow(_PyTime_t a, _PyTime_t b) } -// Compute t * k. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Compute t * k. Clamp to [PyTime_MIN; PyTime_MAX] on overflow. static inline int pytime_mul(_PyTime_t *t, _PyTime_t k) { assert(k >= 0); if (pytime_mul_check_overflow(*t, k)) { - *t = (*t >= 0) ? _PyTime_MAX : _PyTime_MIN; + *t = (*t >= 0) ? PyTime_MAX : PyTime_MIN; return -1; } else { @@ -143,7 +143,7 @@ pytime_mul(_PyTime_t *t, _PyTime_t k) } -// Compute t * k. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +// Compute t * k. Clamp to [PyTime_MIN; PyTime_MAX] on overflow. static inline _PyTime_t _PyTime_Mul(_PyTime_t t, _PyTime_t k) { @@ -416,12 +416,12 @@ _PyTime_FromSeconds(int seconds) /* ensure that integer overflow cannot happen, int type should have 32 bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_NS takes 30 bits). */ - static_assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS, "_PyTime_t overflow"); - static_assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS, "_PyTime_t underflow"); + static_assert(INT_MAX <= PyTime_MAX / SEC_TO_NS, "_PyTime_t overflow"); + static_assert(INT_MIN >= PyTime_MIN / SEC_TO_NS, "_PyTime_t underflow"); _PyTime_t t = (_PyTime_t)seconds; - assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) - || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); + assert((t >= 0 && t <= PyTime_MAX / SEC_TO_NS) + || (t < 0 && t >= PyTime_MIN / SEC_TO_NS)); t *= SEC_TO_NS; return pytime_from_nanoseconds(t); } @@ -544,7 +544,7 @@ pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round, d = pytime_round(d, round); /* See comments in pytime_double_to_denominator */ - if (!((double)_PyTime_MIN <= d && d < -(double)_PyTime_MIN)) { + if (!((double)PyTime_MIN <= d && d < -(double)PyTime_MIN)) { pytime_time_t_overflow(); return -1; } @@ -606,12 +606,12 @@ _PyTime_FromMillisecondsObject(_PyTime_t *tp, PyObject *obj, _PyTime_round_t rou double -_PyTime_AsSecondsDouble(_PyTime_t t) +PyTime_AsSecondsDouble(PyTime_t t) { /* volatile avoids optimization changing how numbers are rounded */ volatile double d; - _PyTime_t ns = pytime_as_nanoseconds(t); + PyTime_t ns = pytime_as_nanoseconds(t); if (ns % SEC_TO_NS == 0) { /* Divide using integers to avoid rounding issues on the integer part. 1e-9 cannot be stored exactly in IEEE 64-bit. */ @@ -652,7 +652,7 @@ pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k) assert(k > 1); if (t >= 0) { // Don't use (t + k - 1) / k to avoid integer overflow - // if t is equal to _PyTime_MAX + // if t is equal to PyTime_MAX _PyTime_t q = t / k; if (t % k) { q += 1; @@ -661,7 +661,7 @@ pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k) } else { // Don't use (t - (k - 1)) / k to avoid integer overflow - // if t is equals to _PyTime_MIN. + // if t is equals to PyTime_MIN. _PyTime_t q = t / k; if (t % k) { q -= 1; @@ -716,7 +716,7 @@ pytime_divide(const _PyTime_t t, const _PyTime_t k, // Compute (t / k, t % k) in (pq, pr). // Make sure that 0 <= pr < k. // Return 0 on success. -// Return -1 on underflow and store (_PyTime_MIN, 0) in (pq, pr). +// Return -1 on underflow and store (PyTime_MIN, 0) in (pq, pr). static int pytime_divmod(const _PyTime_t t, const _PyTime_t k, _PyTime_t *pq, _PyTime_t *pr) @@ -725,8 +725,8 @@ pytime_divmod(const _PyTime_t t, const _PyTime_t k, _PyTime_t q = t / k; _PyTime_t r = t % k; if (r < 0) { - if (q == _PyTime_MIN) { - *pq = _PyTime_MIN; + if (q == PyTime_MIN) { + *pq = PyTime_MIN; *pr = 0; return -1; } @@ -994,10 +994,10 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) } -_PyTime_t -_PyTime_GetSystemClock(void) +PyTime_t +PyTime_GetSystemClock(void) { - _PyTime_t t; + PyTime_t t; if (py_get_system_clock(&t, NULL, 0) < 0) { // If clock_gettime(CLOCK_REALTIME) or gettimeofday() fails: // silently ignore the failure and return 0. @@ -1051,7 +1051,7 @@ py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) None of these time bases can overflow with 64-bit _PyTime_t, but check for overflow, just in case. */ - if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { + if ((_PyTime_t)timebase.numer > PyTime_MAX / (_PyTime_t)timebase.denom) { if (raise) { PyErr_SetString(PyExc_OverflowError, "mach_timebase_info is too large"); @@ -1076,13 +1076,13 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) static_assert(sizeof(ticks) <= sizeof(_PyTime_t), "ULONGLONG is larger than _PyTime_t"); _PyTime_t t; - if (ticks <= (ULONGLONG)_PyTime_MAX) { + if (ticks <= (ULONGLONG)PyTime_MAX) { t = (_PyTime_t)ticks; } else { // GetTickCount64() maximum is larger than _PyTime_t maximum: // ULONGLONG is unsigned, whereas _PyTime_t is signed. - t = _PyTime_MAX; + t = PyTime_MAX; } int res = pytime_mul(&t, MS_TO_NS); @@ -1126,7 +1126,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) uint64_t uticks = mach_absolute_time(); // unsigned => signed - assert(uticks <= (uint64_t)_PyTime_MAX); + assert(uticks <= (uint64_t)PyTime_MAX); _PyTime_t ticks = (_PyTime_t)uticks; _PyTime_t ns = _PyTime_MulDiv(ticks, timebase_numer, timebase_denom); @@ -1191,10 +1191,10 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) } -_PyTime_t -_PyTime_GetMonotonicClock(void) +PyTime_t +PyTime_GetMonotonicClock(void) { - _PyTime_t t; + PyTime_t t; if (py_get_monotonic_clock(&t, NULL, 0) < 0) { // If mach_timebase_info(), clock_gettime() or gethrtime() fails: // silently ignore the failure and return 0. @@ -1235,7 +1235,7 @@ py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise) None of these frequencies can overflow with 64-bit _PyTime_t, but check for integer overflow just in case. */ - if (frequency > _PyTime_MAX / SEC_TO_NS) { + if (frequency > PyTime_MAX / SEC_TO_NS) { if (raise) { PyErr_SetString(PyExc_OverflowError, "QueryPerformanceFrequency is too large"); @@ -1296,10 +1296,10 @@ _PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info) } -_PyTime_t -_PyTime_GetPerfCounter(void) +PyTime_t +PyTime_GetPerfCounter(void) { - _PyTime_t t; + PyTime_t t; int res; #ifdef MS_WINDOWS res = py_get_win_perf_counter(&t, NULL, 0); @@ -1385,7 +1385,7 @@ _PyTime_gmtime(time_t t, struct tm *tm) _PyTime_t _PyDeadline_Init(_PyTime_t timeout) { - _PyTime_t now = _PyTime_GetMonotonicClock(); + _PyTime_t now = PyTime_GetMonotonicClock(); return _PyTime_Add(now, timeout); } @@ -1393,6 +1393,6 @@ _PyDeadline_Init(_PyTime_t timeout) _PyTime_t _PyDeadline_Get(_PyTime_t deadline) { - _PyTime_t now = _PyTime_GetMonotonicClock(); + _PyTime_t now = PyTime_GetMonotonicClock(); return deadline - now; } diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 14b9cddc24c0ec3..c04274b0cd1037b 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -76,16 +76,16 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) } } else if (milliseconds != 0) { /* wait at least until the deadline */ - _PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000); - _PyTime_t deadline = _PyTime_Add(_PyTime_GetPerfCounter(), nanoseconds); + PyTime_t nanoseconds = _PyTime_FromNanoseconds((PyTime_t)milliseconds * 1000000); + PyTime_t deadline = _PyTime_Add(PyTime_GetPerfCounter(), nanoseconds); while (mutex->locked) { - _PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, - _PyTime_ROUND_TIMEOUT); + PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, + _PyTime_ROUND_TIMEOUT); if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) { result = WAIT_FAILED; break; } - nanoseconds = deadline - _PyTime_GetPerfCounter(); + nanoseconds = deadline - PyTime_GetPerfCounter(); if (nanoseconds <= 0) { break; } diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index fb3b79fc160502f..ad410a28eb30e46 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -149,16 +149,16 @@ _PyThread_cond_init(PyCOND_T *cond) void _PyThread_cond_after(long long us, struct timespec *abs) { - _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); - _PyTime_t t; + PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); + PyTime_t t; #ifdef CONDATTR_MONOTONIC if (condattr_monotonic) { - t = _PyTime_GetMonotonicClock(); + t = PyTime_GetMonotonicClock(); } else #endif { - t = _PyTime_GetSystemClock(); + t = PyTime_GetSystemClock(); } t = _PyTime_Add(t, timeout); _PyTime_AsTimespec_clamp(t, abs); @@ -491,13 +491,13 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, (void) error; /* silence unused-but-set-variable warning */ - _PyTime_t timeout; // relative timeout + PyTime_t timeout; // relative timeout if (microseconds >= 0) { // bpo-41710: PyThread_acquire_lock_timed() cannot report timeout // overflow to the caller, so clamp the timeout to - // [_PyTime_MIN, _PyTime_MAX]. + // [PyTime_MIN, PyTime_MAX]. // - // _PyTime_MAX nanoseconds is around 292.3 years. + // PyTime_MAX nanoseconds is around 292.3 years. // // _thread.Lock.acquire() and _thread.RLock.acquire() raise an // OverflowError if microseconds is greater than PY_TIMEOUT_MAX. @@ -511,11 +511,11 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, struct timespec abs_timeout; // Local scope for deadline { - _PyTime_t deadline = _PyTime_Add(_PyTime_GetMonotonicClock(), timeout); + PyTime_t deadline = _PyTime_Add(PyTime_GetMonotonicClock(), timeout); _PyTime_AsTimespec_clamp(deadline, &abs_timeout); } #else - _PyTime_t deadline = 0; + PyTime_t deadline = 0; if (timeout > 0 && !intr_flag) { deadline = _PyDeadline_Init(timeout); } @@ -527,8 +527,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC, &abs_timeout)); #else - _PyTime_t abs_time = _PyTime_Add(_PyTime_GetSystemClock(), - timeout); + PyTime_t abs_time = _PyTime_Add(PyTime_GetSystemClock(), timeout); struct timespec ts; _PyTime_AsTimespec_clamp(abs_time, &ts); status = fix_status(sem_timedwait(thelock, &ts));