1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
"""
Cython implementation of (parts of) the standard library time module.
Note: On implementations that lack a C-API for monotonic/perfcounter clocks
(like PyPy), the fallback code uses the system clock which may return absolute
time values from a different value range, differing from those provided by
Python's "time" module.
"""
from libc.stdint cimport int64_t
from cpython.exc cimport PyErr_SetFromErrno
cdef extern from *:
"""
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_t)
#define __Pyx_PyTime_t PyTime_t
#else
#define __Pyx_PyTime_t _PyTime_t
#endif
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_TimeRaw)
static CYTHON_INLINE __Pyx_PyTime_t __Pyx_PyTime_TimeRaw(void) {
__Pyx_PyTime_t tic;
(void) PyTime_TimeRaw(&tic);
return tic;
}
#else
#define __Pyx_PyTime_TimeRaw() _PyTime_GetSystemClock()
#endif
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_MonotonicRaw)
static CYTHON_INLINE __Pyx_PyTime_t __Pyx_PyTime_MonotonicRaw(void) {
__Pyx_PyTime_t tic;
(void) PyTime_MonotonicRaw(&tic);
return tic;
}
#elif CYTHON_COMPILING_IN_PYPY && !defined(_PyTime_GetMonotonicClock)
#define __Pyx_PyTime_MonotonicRaw() _PyTime_GetSystemClock()
#else
#define __Pyx_PyTime_MonotonicRaw() _PyTime_GetMonotonicClock()
#endif
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_PerfCounterRaw)
static CYTHON_INLINE __Pyx_PyTime_t __Pyx_PyTime_PerfCounterRaw(void) {
__Pyx_PyTime_t tic;
(void) PyTime_PerfCounterRaw(&tic);
return tic;
}
#elif CYTHON_COMPILING_IN_PYPY && !defined(_PyTime_GetPerfCounter)
#define __Pyx_PyTime_PerfCounterRaw() __Pyx_PyTime_MonotonicRaw()
#else
#define __Pyx_PyTime_PerfCounterRaw() _PyTime_GetPerfCounter()
#endif
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_AsSecondsDouble)
#define __Pyx_PyTime_AsSecondsDouble(t) PyTime_AsSecondsDouble(t)
#else
#define __Pyx_PyTime_AsSecondsDouble(t) _PyTime_AsSecondsDouble(t)
#endif
"""
ctypedef int64_t PyTime_t "__Pyx_PyTime_t"
ctypedef PyTime_t _PyTime_t "__Pyx_PyTime_t" # legacy, use "PyTime_t" instead
PyTime_t PyTime_TimeUnchecked "__Pyx_PyTime_TimeRaw" () noexcept nogil # legacy, use "PyTime_TimeRaw" instead
PyTime_t PyTime_TimeRaw "__Pyx_PyTime_TimeRaw" () noexcept nogil
PyTime_t PyTime_MonotonicRaw "__Pyx_PyTime_MonotonicRaw" () noexcept nogil
PyTime_t PyTime_PerfCounterRaw "__Pyx_PyTime_PerfCounterRaw" () noexcept nogil
double PyTime_AsSecondsDouble "__Pyx_PyTime_AsSecondsDouble" (PyTime_t t) noexcept nogil
from libc.time cimport (
tm,
time_t,
localtime as libc_localtime,
)
cdef inline double time() noexcept nogil:
cdef PyTime_t tic = PyTime_TimeRaw()
return PyTime_AsSecondsDouble(tic)
cdef inline int64_t time_ns() noexcept nogil:
return <int64_t> PyTime_TimeRaw()
cdef inline double perf_counter() noexcept nogil:
cdef PyTime_t tic = PyTime_PerfCounterRaw()
return PyTime_AsSecondsDouble(tic)
cdef inline int64_t perf_counter_ns() noexcept nogil:
return <int64_t> PyTime_PerfCounterRaw()
cdef inline double monotonic() noexcept nogil:
cdef PyTime_t tic = PyTime_MonotonicRaw()
return PyTime_AsSecondsDouble(tic)
cdef inline int64_t monotonic_ns() noexcept nogil:
return <int64_t> PyTime_MonotonicRaw()
cdef inline int _raise_from_errno() except -1 with gil:
PyErr_SetFromErrno(RuntimeError)
return <int> -1 # Let the C compiler know that this function always raises.
cdef inline tm localtime() except * nogil:
"""
Analogue to the stdlib time.localtime. The returned struct
has some entries that the stdlib version does not: tm_gmtoff, tm_zone
"""
cdef:
time_t tic = <time_t>time()
tm* result
result = libc_localtime(&tic)
if result is NULL:
_raise_from_errno()
# Fix 0-based date values (and the 1900-based year).
# See tmtotuple() in https://github.com/python/cpython/blob/master/Modules/timemodule.c
result.tm_year += 1900
result.tm_mon += 1
result.tm_wday = <int> ((result.tm_wday + 6) % 7)
result.tm_yday += 1
return result[0]
|