gh-110850: Remove _PyTime_TimeUnchecked() function (#118552)

Use the new public Raw functions:

* _PyTime_PerfCounterUnchecked() with PyTime_PerfCounterRaw()
* _PyTime_TimeUnchecked() with PyTime_TimeRaw()
* _PyTime_MonotonicUnchecked() with PyTime_MonotonicRaw()

Remove internal functions:

* _PyTime_PerfCounterUnchecked()
* _PyTime_TimeUnchecked()
* _PyTime_MonotonicUnchecked()
This commit is contained in:
Victor Stinner 2024-05-05 12:15:19 +02:00 committed by GitHub
parent c7c9b913c0
commit aa61f8bfcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 65 additions and 94 deletions

View File

@ -249,14 +249,6 @@ typedef struct {
double resolution; double resolution;
} _Py_clock_info_t; } _Py_clock_info_t;
// Similar to PyTime_Time() but silently ignore the error and return 0 if the
// internal clock fails.
//
// Use _PyTime_TimeWithInfo() or the public PyTime_Time() to check
// for failure.
// Export for '_random' shared extension.
PyAPI_FUNC(PyTime_t) _PyTime_TimeUnchecked(void);
// Get the current time from the system clock. // Get the current time from the system clock.
// On success, set *t and *info (if not NULL), and return 0. // On success, set *t and *info (if not NULL), and return 0.
// On error, raise an exception and return -1. // On error, raise an exception and return -1.
@ -264,14 +256,6 @@ extern int _PyTime_TimeWithInfo(
PyTime_t *t, PyTime_t *t,
_Py_clock_info_t *info); _Py_clock_info_t *info);
// Similar to PyTime_Monotonic() but silently ignore the error and return 0 if
// the internal clock fails.
//
// Use _PyTime_MonotonicWithInfo() or the public PyTime_Monotonic()
// to check for failure.
// Export for '_random' shared extension.
PyAPI_FUNC(PyTime_t) _PyTime_MonotonicUnchecked(void);
// Get the time of a monotonic clock, i.e. a clock that cannot go backwards. // 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 clock is not affected by system clock updates. The reference point of
// the returned value is undefined, so that only the difference between the // the returned value is undefined, so that only the difference between the
@ -296,14 +280,6 @@ PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
// Export for '_datetime' shared extension. // Export for '_datetime' shared extension.
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
// Similar to PyTime_PerfCounter() but silently ignore the error and return 0
// if the internal clock fails.
//
// Use _PyTime_PerfCounterWithInfo() or the public PyTime_PerfCounter() to
// check for failure.
// Export for '_lsprof' shared extension.
PyAPI_FUNC(PyTime_t) _PyTime_PerfCounterUnchecked(void);
// Get the performance counter: clock with the highest available resolution to // Get the performance counter: clock with the highest available resolution to
// measure a short duration. // measure a short duration.
@ -319,12 +295,12 @@ extern int _PyTime_PerfCounterWithInfo(
// --- _PyDeadline ----------------------------------------------------------- // --- _PyDeadline -----------------------------------------------------------
// Create a deadline. // Create a deadline.
// Pseudo code: _PyTime_MonotonicUnchecked() + timeout. // Pseudo code: return PyTime_MonotonicRaw() + timeout
// Export for '_ssl' shared extension. // Export for '_ssl' shared extension.
PyAPI_FUNC(PyTime_t) _PyDeadline_Init(PyTime_t timeout); PyAPI_FUNC(PyTime_t) _PyDeadline_Init(PyTime_t timeout);
// Get remaining time from a deadline. // Get remaining time from a deadline.
// Pseudo code: deadline - _PyTime_MonotonicUnchecked(). // Pseudo code: return deadline - PyTime_MonotonicRaw()
// Export for '_ssl' shared extension. // Export for '_ssl' shared extension.
PyAPI_FUNC(PyTime_t) _PyDeadline_Get(PyTime_t deadline); PyAPI_FUNC(PyTime_t) _PyDeadline_Get(PyTime_t deadline);

View File

@ -121,7 +121,9 @@ call_timer(ProfilerObject *pObj)
return CallExternalTimer(pObj); return CallExternalTimer(pObj);
} }
else { else {
return _PyTime_PerfCounterUnchecked(); PyTime_t t;
(void)PyTime_PerfCounterRaw(&t);
return t;
} }
} }

View File

@ -2,7 +2,6 @@
#include "parts.h" #include "parts.h"
#include "pycore_lock.h" #include "pycore_lock.h"
#include "pycore_time.h" // _PyTime_MonotonicUnchecked()
#include "clinic/test_lock.c.h" #include "clinic/test_lock.c.h"
@ -290,7 +289,10 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module,
goto exit; goto exit;
} }
PyTime_t start = _PyTime_MonotonicUnchecked(); PyTime_t start, end;
if (PyTime_PerfCounter(&start) < 0) {
goto exit;
}
for (Py_ssize_t i = 0; i < num_threads; i++) { for (Py_ssize_t i = 0; i < num_threads; i++) {
thread_data[i].bench_data = &bench_data; thread_data[i].bench_data = &bench_data;
@ -307,7 +309,9 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module,
} }
Py_ssize_t total_iters = bench_data.total_iters; Py_ssize_t total_iters = bench_data.total_iters;
PyTime_t end = _PyTime_MonotonicUnchecked(); if (PyTime_PerfCounter(&end) < 0) {
goto exit;
}
// Return the total number of acquisitions and the number of acquisitions // Return the total number of acquisitions and the number of acquisitions
// for each thread. // for each thread.
@ -319,7 +323,8 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module,
PyList_SET_ITEM(thread_iters, i, iter); PyList_SET_ITEM(thread_iters, i, iter);
} }
double rate = total_iters * 1000000000.0 / (end - start); assert(end != start);
double rate = total_iters * 1e9 / (end - start);
res = Py_BuildValue("(dO)", rate, thread_iters); res = Py_BuildValue("(dO)", rate, thread_iters);
exit: exit:

View File

@ -12,7 +12,6 @@
#include "pycore_object_alloc.h" // _PyObject_MallocWithType() #include "pycore_object_alloc.h" // _PyObject_MallocWithType()
#include "pycore_pyerrors.h" #include "pycore_pyerrors.h"
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_time.h" // _PyTime_PerfCounterUnchecked()
#include "pycore_weakref.h" // _PyWeakref_ClearRef() #include "pycore_weakref.h" // _PyWeakref_ClearRef()
#include "pydtrace.h" #include "pydtrace.h"

View File

@ -11,7 +11,6 @@
#include "pycore_object_stack.h" #include "pycore_object_stack.h"
#include "pycore_pyerrors.h" #include "pycore_pyerrors.h"
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_time.h" // _PyTime_GetPerfCounter()
#include "pycore_tstate.h" // _PyThreadStateImpl #include "pycore_tstate.h" // _PyThreadStateImpl
#include "pycore_weakref.h" // _PyWeakref_ClearRef() #include "pycore_weakref.h" // _PyWeakref_ClearRef()
#include "pydtrace.h" #include "pydtrace.h"
@ -1164,7 +1163,8 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
if (gcstate->debug & _PyGC_DEBUG_STATS) { if (gcstate->debug & _PyGC_DEBUG_STATS) {
PySys_WriteStderr("gc: collecting generation %d...\n", generation); PySys_WriteStderr("gc: collecting generation %d...\n", generation);
show_stats_each_generations(gcstate); show_stats_each_generations(gcstate);
t1 = _PyTime_PerfCounterUnchecked(); // ignore error: don't interrupt the GC if reading the clock fails
(void)PyTime_PerfCounterRaw(&t1);
} }
if (PyDTrace_GC_START_ENABLED()) { if (PyDTrace_GC_START_ENABLED()) {
@ -1184,7 +1184,9 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
n = state.uncollectable; n = state.uncollectable;
if (gcstate->debug & _PyGC_DEBUG_STATS) { if (gcstate->debug & _PyGC_DEBUG_STATS) {
double d = PyTime_AsSecondsDouble(_PyTime_PerfCounterUnchecked() - t1); PyTime_t t2;
(void)PyTime_PerfCounterRaw(&t2);
double d = PyTime_AsSecondsDouble(t2 - t1);
PySys_WriteStderr( PySys_WriteStderr(
"gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n", "gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n",
n+m, n, d); n+m, n, d);

View File

@ -13,7 +13,7 @@
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_time.h" // _PyTime_PerfCounterUnchecked() #include "pycore_time.h" // _PyTime_AsMicroseconds()
#include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "pycore_weakref.h" // _PyWeakref_GET_REF()
#include "marshal.h" // PyMarshal_ReadObjectFromString() #include "marshal.h" // PyMarshal_ReadObjectFromString()
@ -3468,7 +3468,8 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
#undef header #undef header
import_level++; import_level++;
t1 = _PyTime_PerfCounterUnchecked(); // ignore error: don't block import if reading the clock fails
(void)PyTime_PerfCounterRaw(&t1);
accumulated = 0; accumulated = 0;
} }
@ -3483,7 +3484,9 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
mod != NULL); mod != NULL);
if (import_time) { if (import_time) {
PyTime_t cum = _PyTime_PerfCounterUnchecked() - t1; PyTime_t t2;
(void)PyTime_PerfCounterRaw(&t2);
PyTime_t cum = t2 - t1;
import_level--; import_level--;
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",

View File

@ -5,13 +5,13 @@
#include "pycore_lock.h" #include "pycore_lock.h"
#include "pycore_parking_lot.h" #include "pycore_parking_lot.h"
#include "pycore_semaphore.h" #include "pycore_semaphore.h"
#include "pycore_time.h" // _PyTime_MonotonicUnchecked() #include "pycore_time.h" // _PyTime_Add()
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
# include <windows.h> // SwitchToThread() # include <windows.h> // SwitchToThread()
#elif defined(HAVE_SCHED_H) #elif defined(HAVE_SCHED_H)
# include <sched.h> // sched_yield() # include <sched.h> // sched_yield()
#endif #endif
// If a thread waits on a lock for longer than TIME_TO_BE_FAIR_NS (1 ms), then // If a thread waits on a lock for longer than TIME_TO_BE_FAIR_NS (1 ms), then
@ -66,7 +66,9 @@ _PyMutex_LockTimed(PyMutex *m, PyTime_t timeout, _PyLockFlags flags)
return PY_LOCK_FAILURE; return PY_LOCK_FAILURE;
} }
PyTime_t now = _PyTime_MonotonicUnchecked(); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
PyTime_t endtime = 0; PyTime_t endtime = 0;
if (timeout > 0) { if (timeout > 0) {
endtime = _PyTime_Add(now, timeout); endtime = _PyTime_Add(now, timeout);
@ -143,7 +145,9 @@ mutex_unpark(PyMutex *m, struct mutex_entry *entry, int has_more_waiters)
{ {
uint8_t v = 0; uint8_t v = 0;
if (entry) { if (entry) {
PyTime_t now = _PyTime_MonotonicUnchecked(); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
int should_be_fair = now > entry->time_to_be_fair; int should_be_fair = now > entry->time_to_be_fair;
entry->handed_off = should_be_fair; entry->handed_off = should_be_fair;

View File

@ -6,7 +6,7 @@
#include "pycore_pyerrors.h" // _Py_FatalErrorFormat #include "pycore_pyerrors.h" // _Py_FatalErrorFormat
#include "pycore_pystate.h" // _PyThreadState_GET #include "pycore_pystate.h" // _PyThreadState_GET
#include "pycore_semaphore.h" // _PySemaphore #include "pycore_semaphore.h" // _PySemaphore
#include "pycore_time.h" //_PyTime_MonotonicUnchecked() #include "pycore_time.h" // _PyTime_Add()
#include <stdbool.h> #include <stdbool.h>
@ -120,13 +120,18 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout)
struct timespec ts; struct timespec ts;
#if defined(CLOCK_MONOTONIC) && defined(HAVE_SEM_CLOCKWAIT) #if defined(CLOCK_MONOTONIC) && defined(HAVE_SEM_CLOCKWAIT)
PyTime_t deadline = _PyTime_Add(_PyTime_MonotonicUnchecked(), timeout); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
PyTime_t deadline = _PyTime_Add(now, timeout);
_PyTime_AsTimespec_clamp(deadline, &ts); _PyTime_AsTimespec_clamp(deadline, &ts);
err = sem_clockwait(&sema->platform_sem, CLOCK_MONOTONIC, &ts); err = sem_clockwait(&sema->platform_sem, CLOCK_MONOTONIC, &ts);
#else #else
PyTime_t deadline = _PyTime_Add(_PyTime_TimeUnchecked(), timeout); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_TimeRaw(&now);
PyTime_t deadline = _PyTime_Add(now, timeout);
_PyTime_AsTimespec_clamp(deadline, &ts); _PyTime_AsTimespec_clamp(deadline, &ts);
@ -163,7 +168,9 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout)
_PyTime_AsTimespec_clamp(timeout, &ts); _PyTime_AsTimespec_clamp(timeout, &ts);
err = pthread_cond_timedwait_relative_np(&sema->cond, &sema->mutex, &ts); err = pthread_cond_timedwait_relative_np(&sema->cond, &sema->mutex, &ts);
#else #else
PyTime_t deadline = _PyTime_Add(_PyTime_TimeUnchecked(), timeout); PyTime_t now;
(void)PyTime_TimeRaw(&now);
PyTime_t deadline = _PyTime_Add(now, timeout);
_PyTime_AsTimespec_clamp(deadline, &ts); _PyTime_AsTimespec_clamp(deadline, &ts);
err = pthread_cond_timedwait(&sema->cond, &sema->mutex, &ts); err = pthread_cond_timedwait(&sema->cond, &sema->mutex, &ts);

View File

@ -1030,22 +1030,6 @@ PyTime_TimeRaw(PyTime_t *result)
} }
PyTime_t
_PyTime_TimeUnchecked(void)
{
PyTime_t t;
#ifdef Py_DEBUG
int result = PyTime_TimeRaw(&t);
if (result != 0) {
Py_FatalError("unable to read the system clock");
}
#else
(void)PyTime_TimeRaw(&t);
#endif
return t;
}
int int
_PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info) _PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info)
{ {
@ -1270,22 +1254,6 @@ PyTime_MonotonicRaw(PyTime_t *result)
} }
PyTime_t
_PyTime_MonotonicUnchecked(void)
{
PyTime_t t;
#ifdef Py_DEBUG
int result = PyTime_MonotonicRaw(&t);
if (result != 0) {
Py_FatalError("unable to read the monotonic clock");
}
#else
(void)PyTime_MonotonicRaw(&t);
#endif
return t;
}
int int
_PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info) _PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{ {
@ -1314,13 +1282,6 @@ PyTime_PerfCounterRaw(PyTime_t *result)
} }
PyTime_t
_PyTime_PerfCounterUnchecked(void)
{
return _PyTime_MonotonicUnchecked();
}
int int
_PyTime_localtime(time_t t, struct tm *tm) _PyTime_localtime(time_t t, struct tm *tm)
{ {
@ -1391,7 +1352,9 @@ _PyTime_gmtime(time_t t, struct tm *tm)
PyTime_t PyTime_t
_PyDeadline_Init(PyTime_t timeout) _PyDeadline_Init(PyTime_t timeout)
{ {
PyTime_t now = _PyTime_MonotonicUnchecked(); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
return _PyTime_Add(now, timeout); return _PyTime_Add(now, timeout);
} }
@ -1399,6 +1362,8 @@ _PyDeadline_Init(PyTime_t timeout)
PyTime_t PyTime_t
_PyDeadline_Get(PyTime_t deadline) _PyDeadline_Get(PyTime_t deadline)
{ {
PyTime_t now = _PyTime_MonotonicUnchecked(); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
return deadline - now; return deadline - now;
} }

View File

@ -158,12 +158,14 @@ _PyThread_cond_after(long long us, struct timespec *abs)
PyTime_t t; PyTime_t t;
#ifdef CONDATTR_MONOTONIC #ifdef CONDATTR_MONOTONIC
if (condattr_monotonic) { if (condattr_monotonic) {
t = _PyTime_MonotonicUnchecked(); // silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&t);
} }
else else
#endif #endif
{ {
t = _PyTime_TimeUnchecked(); // silently ignore error: cannot report error to the caller
(void)PyTime_TimeRaw(&t);
} }
t = _PyTime_Add(t, timeout); t = _PyTime_Add(t, timeout);
_PyTime_AsTimespec_clamp(t, abs); _PyTime_AsTimespec_clamp(t, abs);
@ -506,7 +508,10 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
struct timespec abs_timeout; struct timespec abs_timeout;
// Local scope for deadline // Local scope for deadline
{ {
PyTime_t deadline = _PyTime_Add(_PyTime_MonotonicUnchecked(), timeout); PyTime_t now;
// silently ignore error: cannot report error to the caller
(void)PyTime_MonotonicRaw(&now);
PyTime_t deadline = _PyTime_Add(now, timeout);
_PyTime_AsTimespec_clamp(deadline, &abs_timeout); _PyTime_AsTimespec_clamp(deadline, &abs_timeout);
} }
#else #else
@ -522,8 +527,11 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC, status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC,
&abs_timeout)); &abs_timeout));
#else #else
PyTime_t abs_time = _PyTime_Add(_PyTime_TimeUnchecked(), PyTime_t now;
timeout); // silently ignore error: cannot report error to the caller
(void)PyTime_TimeRaw(&now);
PyTime_t abs_time = _PyTime_Add(now, timeout);
struct timespec ts; struct timespec ts;
_PyTime_AsTimespec_clamp(abs_time, &ts); _PyTime_AsTimespec_clamp(abs_time, &ts);
status = fix_status(sem_timedwait(thelock, &ts)); status = fix_status(sem_timedwait(thelock, &ts));