#include "Python.h"
#include "pycore_time.h"
#include <time.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef MS_WINDOWS
# include <winsock2.h>
#endif
#if defined(__APPLE__)
# include <mach/mach_time.h>
#if defined(__APPLE__) && defined(__has_builtin)
# if __has_builtin(__builtin_available)
#define HAVE_CLOCK_GETTIME_RUNTIME …
# endif
#endif
#endif
#define SEC_TO_MS …
#define MS_TO_US …
#define SEC_TO_US …
#define US_TO_NS …
#define MS_TO_NS …
#define SEC_TO_NS …
#define NS_TO_MS …
#define NS_TO_US …
#define NS_TO_100NS …
#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
#define PY_TIME_T_MAX …
#define PY_TIME_T_MIN …
#elif SIZEOF_TIME_T == SIZEOF_LONG
#define PY_TIME_T_MAX …
#define PY_TIME_T_MIN …
#else
# error "unsupported time_t size"
#endif
#if PY_TIME_T_MAX + PY_TIME_T_MIN != -1
# error "time_t is not a two's complement integer type"
#endif
#if PyTime_MIN + PyTime_MAX != -1
# error "PyTime_t is not a two's complement integer type"
#endif
#ifdef MS_WINDOWS
static _PyTimeFraction py_qpc_base = {0, 0};
static int py_win_perf_counter_frequency(_PyTimeFraction *base, int raise_exc);
#endif
static PyTime_t
_PyTime_GCD(PyTime_t x, PyTime_t y)
{ … }
int
_PyTimeFraction_Set(_PyTimeFraction *frac, PyTime_t numer, PyTime_t denom)
{ … }
double
_PyTimeFraction_Resolution(const _PyTimeFraction *frac)
{ … }
static void
pytime_time_t_overflow(void)
{ … }
static void
pytime_overflow(void)
{ … }
static inline int
pytime_add(PyTime_t *t1, PyTime_t t2)
{ … }
PyTime_t
_PyTime_Add(PyTime_t t1, PyTime_t t2)
{ … }
static inline int
pytime_mul_check_overflow(PyTime_t a, PyTime_t b)
{ … }
static inline int
pytime_mul(PyTime_t *t, PyTime_t k)
{ … }
static inline PyTime_t
_PyTime_Mul(PyTime_t t, PyTime_t k)
{ … }
PyTime_t
_PyTimeFraction_Mul(PyTime_t ticks, const _PyTimeFraction *frac)
{ … }
time_t
_PyLong_AsTime_t(PyObject *obj)
{ … }
PyObject *
_PyLong_FromTime_t(time_t t)
{ … }
static int
_PyTime_AsTime_t(PyTime_t t, time_t *t2)
{ … }
#ifdef MS_WINDOWS
static int
_PyTime_AsCLong(PyTime_t t, long *t2)
{
#if SIZEOF_LONG < _SIZEOF_PYTIME_T
if ((PyTime_t)LONG_MAX < t) {
*t2 = LONG_MAX;
return -1;
}
if (t < (PyTime_t)LONG_MIN) {
*t2 = LONG_MIN;
return -1;
}
#endif
*t2 = (long)t;
return 0;
}
#endif
static double
pytime_round_half_even(double x)
{ … }
static double
pytime_round(double x, _PyTime_round_t round)
{ … }
static int
pytime_double_to_denominator(double d, time_t *sec, long *numerator,
long idenominator, _PyTime_round_t round)
{ … }
static int
pytime_object_to_denominator(PyObject *obj, time_t *sec, long *numerator,
long denominator, _PyTime_round_t round)
{ … }
int
_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
{ … }
int
_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
_PyTime_round_t round)
{ … }
int
_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
_PyTime_round_t round)
{ … }
PyTime_t
_PyTime_FromSeconds(int seconds)
{ … }
PyTime_t
_PyTime_FromMicrosecondsClamp(PyTime_t us)
{ … }
int
_PyTime_FromLong(PyTime_t *tp, PyObject *obj)
{ … }
#ifdef HAVE_CLOCK_GETTIME
static int
pytime_fromtimespec(PyTime_t *tp, const struct timespec *ts, int raise_exc)
{ … }
int
_PyTime_FromTimespec(PyTime_t *tp, const struct timespec *ts)
{ … }
#endif
#ifndef MS_WINDOWS
static int
pytime_fromtimeval(PyTime_t *tp, struct timeval *tv, int raise_exc)
{ … }
int
_PyTime_FromTimeval(PyTime_t *tp, struct timeval *tv)
{ … }
#endif
static int
pytime_from_double(PyTime_t *tp, double value, _PyTime_round_t round,
long unit_to_ns)
{ … }
static int
pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round,
long unit_to_ns)
{ … }
int
_PyTime_FromSecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
{ … }
int
_PyTime_FromMillisecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
{ … }
double
PyTime_AsSecondsDouble(PyTime_t ns)
{ … }
PyObject *
_PyTime_AsLong(PyTime_t ns)
{ … }
int
_PyTime_FromSecondsDouble(double seconds, _PyTime_round_t round, PyTime_t *result)
{ … }
static PyTime_t
pytime_divide_round_up(const PyTime_t t, const PyTime_t k)
{ … }
static PyTime_t
pytime_divide(const PyTime_t t, const PyTime_t k,
const _PyTime_round_t round)
{ … }
static int
pytime_divmod(const PyTime_t t, const PyTime_t k,
PyTime_t *pq, PyTime_t *pr)
{ … }
#ifdef MS_WINDOWS
PyTime_t
_PyTime_As100Nanoseconds(PyTime_t ns, _PyTime_round_t round)
{
return pytime_divide(ns, NS_TO_100NS, round);
}
#endif
PyTime_t
_PyTime_AsMicroseconds(PyTime_t ns, _PyTime_round_t round)
{ … }
PyTime_t
_PyTime_AsMilliseconds(PyTime_t ns, _PyTime_round_t round)
{ … }
static int
pytime_as_timeval(PyTime_t ns, PyTime_t *ptv_sec, int *ptv_usec,
_PyTime_round_t round)
{ … }
static int
pytime_as_timeval_struct(PyTime_t t, struct timeval *tv,
_PyTime_round_t round, int raise_exc)
{ … }
int
_PyTime_AsTimeval(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{ … }
void
_PyTime_AsTimeval_clamp(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{ … }
int
_PyTime_AsTimevalTime_t(PyTime_t t, time_t *p_secs, int *us,
_PyTime_round_t round)
{ … }
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
static int
pytime_as_timespec(PyTime_t ns, struct timespec *ts, int raise_exc)
{ … }
void
_PyTime_AsTimespec_clamp(PyTime_t t, struct timespec *ts)
{ … }
int
_PyTime_AsTimespec(PyTime_t t, struct timespec *ts)
{ … }
#endif
static int
py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{ … }
int
PyTime_Time(PyTime_t *result)
{ … }
int
PyTime_TimeRaw(PyTime_t *result)
{ … }
int
_PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info)
{ … }
#ifdef MS_WINDOWS
static int
py_win_perf_counter_frequency(_PyTimeFraction *base, int raise_exc)
{
LARGE_INTEGER freq;
(void)QueryPerformanceFrequency(&freq);
LONGLONG frequency = freq.QuadPart;
assert(frequency >= 1);
Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(frequency));
PyTime_t denom = (PyTime_t)frequency;
if (_PyTimeFraction_Set(base, SEC_TO_NS, denom) < 0) {
if (raise_exc) {
PyErr_SetString(PyExc_RuntimeError,
"invalid QueryPerformanceFrequency");
}
return -1;
}
return 0;
}
static int
py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{
assert(info == NULL || raise_exc);
if (py_qpc_base.denom == 0) {
if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
return -1;
}
}
if (info) {
info->implementation = "QueryPerformanceCounter()";
info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
info->monotonic = 1;
info->adjustable = 0;
}
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
LONGLONG ticksll = now.QuadPart;
PyTime_t ticks;
static_assert(sizeof(ticksll) <= sizeof(ticks),
"LONGLONG is larger than PyTime_t");
ticks = (PyTime_t)ticksll;
*tp = _PyTimeFraction_Mul(ticks, &py_qpc_base);
return 0;
}
#endif
#ifdef __APPLE__
static int
py_mach_timebase_info(_PyTimeFraction *base, int raise_exc)
{
mach_timebase_info_data_t timebase;
(void)mach_timebase_info(&timebase);
Py_BUILD_ASSERT(sizeof(timebase.numer) <= sizeof(PyTime_t));
Py_BUILD_ASSERT(sizeof(timebase.denom) <= sizeof(PyTime_t));
PyTime_t numer = (PyTime_t)timebase.numer;
PyTime_t denom = (PyTime_t)timebase.denom;
if (_PyTimeFraction_Set(base, numer, denom) < 0) {
if (raise_exc) {
PyErr_SetString(PyExc_RuntimeError,
"invalid mach_timebase_info");
}
return -1;
}
return 0;
}
#endif
static int
py_get_monotonic_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{ … }
int
PyTime_Monotonic(PyTime_t *result)
{ … }
int
PyTime_MonotonicRaw(PyTime_t *result)
{ … }
int
_PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{ … }
int
_PyTime_PerfCounterWithInfo(PyTime_t *t, _Py_clock_info_t *info)
{ … }
int
PyTime_PerfCounter(PyTime_t *result)
{ … }
int
PyTime_PerfCounterRaw(PyTime_t *result)
{ … }
int
_PyTime_localtime(time_t t, struct tm *tm)
{ … }
int
_PyTime_gmtime(time_t t, struct tm *tm)
{ … }
PyTime_t
_PyDeadline_Init(PyTime_t timeout)
{ … }
PyTime_t
_PyDeadline_Get(PyTime_t deadline)
{ … }