_PyTime_t _PyTime_FromSeconds(int seconds) { _PyTime_t t; t = (_PyTime_t)seconds; /* ensure that integer overflow cannot happen, int type should have 32 bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 bits). */ Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); Py_BUILD_ASSERT(INT_MIN >= _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 t; }
static int _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, long unit_to_ns) { if (PyFloat_Check(obj)) { double d; d = PyFloat_AsDouble(obj); return _PyTime_FromFloatObject(t, d, round, unit_to_ns); } else { long long sec; Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); sec = PyLong_AsLongLong(obj); if (sec == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) _PyTime_overflow(); return -1; } if (_PyTime_check_mul_overflow(sec, unit_to_ns)) { _PyTime_overflow(); return -1; } *t = sec * unit_to_ns; return 0; } }
_PyTime_t _PyTime_FromNanoseconds(long long ns) { _PyTime_t t; Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); t = Py_SAFE_DOWNCAST(ns, long long, _PyTime_t); return t; }
PyObject * _PyLong_FromTime_t(time_t t) { #if SIZEOF_TIME_T == SIZEOF_LONG_LONG return PyLong_FromLongLong((long long)t); #else Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); return PyLong_FromLong((long)t); #endif }
time_t _PyLong_AsTime_t(PyObject *obj) { #if SIZEOF_TIME_T == SIZEOF_LONG_LONG long long val; val = PyLong_AsLongLong(obj); #else long val; Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); val = PyLong_AsLong(obj); #endif if (val == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) error_time_t_overflow(); return -1; } return (time_t)val; }
int PySlice_Unpack(PyObject *_r, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ Py_BUILD_ASSERT(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX); if (r->step == Py_None) { *step = 1; } else { if (!_PyEval_SliceIndex(r->step, step)) return -1; if (*step == 0) { PyErr_SetString(PyExc_ValueError, "slice step cannot be zero"); return -1; } /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it * guards against later undefined behaviour resulting from code that * does "step = -step" as part of a slice reversal. */ if (*step < -PY_SSIZE_T_MAX) *step = -PY_SSIZE_T_MAX; } if (r->start == Py_None) { *start = *step < 0 ? PY_SSIZE_T_MAX : 0; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; } if (r->stop == Py_None) { *stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; } return 0; }
static int _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise) { _PyTime_t t; int res = 0; Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); t = (_PyTime_t)tv->tv_sec; if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { if (raise) _PyTime_overflow(); res = -1; } t = t * SEC_TO_NS; t += (_PyTime_t)tv->tv_usec * US_TO_NS; *tp = t; return res; }
static int pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) { #if defined(MS_WINDOWS) ULONGLONG ticks; _PyTime_t t; assert(info == NULL || raise); ticks = GetTickCount64(); Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); t = (_PyTime_t)ticks; if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { if (raise) { _PyTime_overflow(); return -1; } /* Hello, time traveler! */ assert(0); } *tp = t * MS_TO_NS; if (info) { DWORD timeAdjustment, timeIncrement; BOOL isTimeAdjustmentDisabled, ok; info->implementation = "GetTickCount64()"; info->monotonic = 1; ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, &isTimeAdjustmentDisabled); if (!ok) { PyErr_SetFromWindowsErr(0); return -1; } info->resolution = timeIncrement * 1e-7; info->adjustable = 0; } #elif defined(__APPLE__) static mach_timebase_info_data_t timebase; uint64_t time; if (timebase.denom == 0) { /* According to the Technical Q&A QA1398, mach_timebase_info() cannot fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ (void)mach_timebase_info(&timebase); } time = mach_absolute_time(); /* apply timebase factor */ time *= timebase.numer; time /= timebase.denom; *tp = time; if (info) { info->implementation = "mach_absolute_time()"; info->resolution = (double)timebase.numer / timebase.denom * 1e-9; info->monotonic = 1; info->adjustable = 0; } #else struct timespec ts; #ifdef CLOCK_HIGHRES const clockid_t clk_id = CLOCK_HIGHRES; const char *implementation = "clock_gettime(CLOCK_HIGHRES)"; #else const clockid_t clk_id = CLOCK_MONOTONIC; const char *implementation = "clock_gettime(CLOCK_MONOTONIC)"; #endif assert(info == NULL || raise); if (clock_gettime(clk_id, &ts) != 0) { if (raise) { PyErr_SetFromErrno(PyExc_OSError); return -1; } return -1; } if (info) { struct timespec res; info->monotonic = 1; info->implementation = implementation; info->adjustable = 0; if (clock_getres(clk_id, &res) != 0) { PyErr_SetFromErrno(PyExc_OSError); return -1; } info->resolution = res.tv_sec + res.tv_nsec * 1e-9; } if (_PyTime_FromTimespec(tp, &ts, raise) < 0) return -1; #endif return 0; }
PyObject * _PyTime_AsNanosecondsObject(_PyTime_t t) { Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); return PyLong_FromLongLong((long long)t); }