xref: /third_party/python/Python/pytime.c (revision 7db96d56)
1#include "Python.h"
2#ifdef MS_WINDOWS
3#  include <winsock2.h>           // struct timeval
4#endif
5
6#if defined(__APPLE__)
7#  include <mach/mach_time.h>     // mach_absolute_time(), mach_timebase_info()
8
9#if defined(__APPLE__) && defined(__has_builtin)
10#  if __has_builtin(__builtin_available)
11#    define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
12#  endif
13#endif
14#endif
15
16/* To millisecond (10^-3) */
17#define SEC_TO_MS 1000
18
19/* To microseconds (10^-6) */
20#define MS_TO_US 1000
21#define SEC_TO_US (SEC_TO_MS * MS_TO_US)
22
23/* To nanoseconds (10^-9) */
24#define US_TO_NS 1000
25#define MS_TO_NS (MS_TO_US * US_TO_NS)
26#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
27
28/* Conversion from nanoseconds */
29#define NS_TO_MS (1000 * 1000)
30#define NS_TO_US (1000)
31#define NS_TO_100NS (100)
32
33#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
34#  define PY_TIME_T_MAX LLONG_MAX
35#  define PY_TIME_T_MIN LLONG_MIN
36#elif SIZEOF_TIME_T == SIZEOF_LONG
37#  define PY_TIME_T_MAX LONG_MAX
38#  define PY_TIME_T_MIN LONG_MIN
39#else
40#  error "unsupported time_t size"
41#endif
42
43#if PY_TIME_T_MAX + PY_TIME_T_MIN != -1
44#  error "time_t is not a two's complement integer type"
45#endif
46
47#if _PyTime_MIN + _PyTime_MAX != -1
48#  error "_PyTime_t is not a two's complement integer type"
49#endif
50
51
52static void
53pytime_time_t_overflow(void)
54{
55    PyErr_SetString(PyExc_OverflowError,
56                    "timestamp out of range for platform time_t");
57}
58
59
60static void
61pytime_overflow(void)
62{
63    PyErr_SetString(PyExc_OverflowError,
64                    "timestamp too large to convert to C _PyTime_t");
65}
66
67
68static inline _PyTime_t
69pytime_from_nanoseconds(_PyTime_t t)
70{
71    // _PyTime_t is a number of nanoseconds
72    return t;
73}
74
75
76static inline _PyTime_t
77pytime_as_nanoseconds(_PyTime_t t)
78{
79    // _PyTime_t is a number of nanoseconds: see pytime_from_nanoseconds()
80    return t;
81}
82
83
84// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
85static inline int
86pytime_add(_PyTime_t *t1, _PyTime_t t2)
87{
88    if (t2 > 0 && *t1 > _PyTime_MAX - t2) {
89        *t1 = _PyTime_MAX;
90        return -1;
91    }
92    else if (t2 < 0 && *t1 < _PyTime_MIN - t2) {
93        *t1 = _PyTime_MIN;
94        return -1;
95    }
96    else {
97        *t1 += t2;
98        return 0;
99    }
100}
101
102
103_PyTime_t
104_PyTime_Add(_PyTime_t t1, _PyTime_t t2)
105{
106    (void)pytime_add(&t1, t2);
107    return t1;
108}
109
110
111static inline int
112pytime_mul_check_overflow(_PyTime_t a, _PyTime_t b)
113{
114    if (b != 0) {
115        assert(b > 0);
116        return ((a < _PyTime_MIN / b) || (_PyTime_MAX / b < a));
117    }
118    else {
119        return 0;
120    }
121}
122
123
124// Compute t * k. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
125static inline int
126pytime_mul(_PyTime_t *t, _PyTime_t k)
127{
128    assert(k >= 0);
129    if (pytime_mul_check_overflow(*t, k)) {
130        *t = (*t >= 0) ? _PyTime_MAX : _PyTime_MIN;
131        return -1;
132    }
133    else {
134        *t *= k;
135        return 0;
136    }
137}
138
139
140// Compute t * k. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
141static inline _PyTime_t
142_PyTime_Mul(_PyTime_t t, _PyTime_t k)
143{
144    (void)pytime_mul(&t, k);
145    return t;
146}
147
148
149
150
151_PyTime_t
152_PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div)
153{
154    /* Compute (ticks * mul / div) in two parts to reduce the risk of integer
155       overflow: compute the integer part, and then the remaining part.
156
157       (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div
158    */
159    _PyTime_t intpart, remaining;
160    intpart = ticks / div;
161    ticks %= div;
162    remaining = _PyTime_Mul(ticks, mul) / div;
163    // intpart * mul + remaining
164    return _PyTime_Add(_PyTime_Mul(intpart, mul), remaining);
165}
166
167
168time_t
169_PyLong_AsTime_t(PyObject *obj)
170{
171#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
172    long long val = PyLong_AsLongLong(obj);
173#elif SIZEOF_TIME_T <= SIZEOF_LONG
174    long val = PyLong_AsLong(obj);
175#else
176#   error "unsupported time_t size"
177#endif
178    if (val == -1 && PyErr_Occurred()) {
179        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
180            pytime_time_t_overflow();
181        }
182        return -1;
183    }
184    return (time_t)val;
185}
186
187
188PyObject *
189_PyLong_FromTime_t(time_t t)
190{
191#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
192    return PyLong_FromLongLong((long long)t);
193#elif SIZEOF_TIME_T <= SIZEOF_LONG
194    return PyLong_FromLong((long)t);
195#else
196#   error "unsupported time_t size"
197#endif
198}
199
200
201// Convert _PyTime_t to time_t.
202// Return 0 on success. Return -1 and clamp the value on overflow.
203static int
204_PyTime_AsTime_t(_PyTime_t t, time_t *t2)
205{
206#if SIZEOF_TIME_T < _SIZEOF_PYTIME_T
207    if ((_PyTime_t)PY_TIME_T_MAX < t) {
208        *t2 = PY_TIME_T_MAX;
209        return -1;
210    }
211    if (t < (_PyTime_t)PY_TIME_T_MIN) {
212        *t2 = PY_TIME_T_MIN;
213        return -1;
214    }
215#endif
216    *t2 = (time_t)t;
217    return 0;
218}
219
220
221#ifdef MS_WINDOWS
222// Convert _PyTime_t to long.
223// Return 0 on success. Return -1 and clamp the value on overflow.
224static int
225_PyTime_AsLong(_PyTime_t t, long *t2)
226{
227#if SIZEOF_LONG < _SIZEOF_PYTIME_T
228    if ((_PyTime_t)LONG_MAX < t) {
229        *t2 = LONG_MAX;
230        return -1;
231    }
232    if (t < (_PyTime_t)LONG_MIN) {
233        *t2 = LONG_MIN;
234        return -1;
235    }
236#endif
237    *t2 = (long)t;
238    return 0;
239}
240#endif
241
242
243/* Round to nearest with ties going to nearest even integer
244   (_PyTime_ROUND_HALF_EVEN) */
245static double
246pytime_round_half_even(double x)
247{
248    double rounded = round(x);
249    if (fabs(x-rounded) == 0.5) {
250        /* halfway case: round to even */
251        rounded = 2.0 * round(x / 2.0);
252    }
253    return rounded;
254}
255
256
257static double
258pytime_round(double x, _PyTime_round_t round)
259{
260    /* volatile avoids optimization changing how numbers are rounded */
261    volatile double d;
262
263    d = x;
264    if (round == _PyTime_ROUND_HALF_EVEN) {
265        d = pytime_round_half_even(d);
266    }
267    else if (round == _PyTime_ROUND_CEILING) {
268        d = ceil(d);
269    }
270    else if (round == _PyTime_ROUND_FLOOR) {
271        d = floor(d);
272    }
273    else {
274        assert(round == _PyTime_ROUND_UP);
275        d = (d >= 0.0) ? ceil(d) : floor(d);
276    }
277    return d;
278}
279
280
281static int
282pytime_double_to_denominator(double d, time_t *sec, long *numerator,
283                             long idenominator, _PyTime_round_t round)
284{
285    double denominator = (double)idenominator;
286    double intpart;
287    /* volatile avoids optimization changing how numbers are rounded */
288    volatile double floatpart;
289
290    floatpart = modf(d, &intpart);
291
292    floatpart *= denominator;
293    floatpart = pytime_round(floatpart, round);
294    if (floatpart >= denominator) {
295        floatpart -= denominator;
296        intpart += 1.0;
297    }
298    else if (floatpart < 0) {
299        floatpart += denominator;
300        intpart -= 1.0;
301    }
302    assert(0.0 <= floatpart && floatpart < denominator);
303
304    /*
305       Conversion of an out-of-range value to time_t gives undefined behaviour
306       (C99 §6.3.1.4p1), so we must guard against it. However, checking that
307       `intpart` is in range is delicate: the obvious expression `intpart <=
308       PY_TIME_T_MAX` will first convert the value `PY_TIME_T_MAX` to a double,
309       potentially changing its value and leading to us failing to catch some
310       UB-inducing values. The code below works correctly under the mild
311       assumption that time_t is a two's complement integer type with no trap
312       representation, and that `PY_TIME_T_MIN` is within the representable
313       range of a C double.
314
315       Note: we want the `if` condition below to be true for NaNs; therefore,
316       resist any temptation to simplify by applying De Morgan's laws.
317    */
318    if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
319        pytime_time_t_overflow();
320        return -1;
321    }
322    *sec = (time_t)intpart;
323    *numerator = (long)floatpart;
324    assert(0 <= *numerator && *numerator < idenominator);
325    return 0;
326}
327
328
329static int
330pytime_object_to_denominator(PyObject *obj, time_t *sec, long *numerator,
331                             long denominator, _PyTime_round_t round)
332{
333    assert(denominator >= 1);
334
335    if (PyFloat_Check(obj)) {
336        double d = PyFloat_AsDouble(obj);
337        if (Py_IS_NAN(d)) {
338            *numerator = 0;
339            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
340            return -1;
341        }
342        return pytime_double_to_denominator(d, sec, numerator,
343                                            denominator, round);
344    }
345    else {
346        *sec = _PyLong_AsTime_t(obj);
347        *numerator = 0;
348        if (*sec == (time_t)-1 && PyErr_Occurred()) {
349            return -1;
350        }
351        return 0;
352    }
353}
354
355
356int
357_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
358{
359    if (PyFloat_Check(obj)) {
360        double intpart;
361        /* volatile avoids optimization changing how numbers are rounded */
362        volatile double d;
363
364        d = PyFloat_AsDouble(obj);
365        if (Py_IS_NAN(d)) {
366            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
367            return -1;
368        }
369
370        d = pytime_round(d, round);
371        (void)modf(d, &intpart);
372
373        /* See comments in pytime_double_to_denominator */
374        if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
375            pytime_time_t_overflow();
376            return -1;
377        }
378        *sec = (time_t)intpart;
379        return 0;
380    }
381    else {
382        *sec = _PyLong_AsTime_t(obj);
383        if (*sec == (time_t)-1 && PyErr_Occurred()) {
384            return -1;
385        }
386        return 0;
387    }
388}
389
390
391int
392_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
393                         _PyTime_round_t round)
394{
395    return pytime_object_to_denominator(obj, sec, nsec, SEC_TO_NS, round);
396}
397
398
399int
400_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
401                        _PyTime_round_t round)
402{
403    return pytime_object_to_denominator(obj, sec, usec, SEC_TO_US, round);
404}
405
406
407_PyTime_t
408_PyTime_FromSeconds(int seconds)
409{
410    /* ensure that integer overflow cannot happen, int type should have 32
411       bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_NS takes 30
412       bits). */
413    static_assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS, "_PyTime_t overflow");
414    static_assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS, "_PyTime_t underflow");
415
416    _PyTime_t t = (_PyTime_t)seconds;
417    assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS)
418           || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS));
419    t *= SEC_TO_NS;
420    return pytime_from_nanoseconds(t);
421}
422
423
424_PyTime_t
425_PyTime_FromNanoseconds(_PyTime_t ns)
426{
427    return pytime_from_nanoseconds(ns);
428}
429
430
431int
432_PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj)
433{
434
435    if (!PyLong_Check(obj)) {
436        PyErr_Format(PyExc_TypeError, "expect int, got %s",
437                     Py_TYPE(obj)->tp_name);
438        return -1;
439    }
440
441    static_assert(sizeof(long long) == sizeof(_PyTime_t),
442                  "_PyTime_t is not long long");
443    long long nsec = PyLong_AsLongLong(obj);
444    if (nsec == -1 && PyErr_Occurred()) {
445        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
446            pytime_overflow();
447        }
448        return -1;
449    }
450
451    _PyTime_t t = (_PyTime_t)nsec;
452    *tp = pytime_from_nanoseconds(t);
453    return 0;
454}
455
456
457#ifdef HAVE_CLOCK_GETTIME
458static int
459pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise_exc)
460{
461    _PyTime_t t, tv_nsec;
462
463    static_assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t),
464                  "timespec.tv_sec is larger than _PyTime_t");
465    t = (_PyTime_t)ts->tv_sec;
466
467    int res1 = pytime_mul(&t, SEC_TO_NS);
468
469    tv_nsec = ts->tv_nsec;
470    int res2 = pytime_add(&t, tv_nsec);
471
472    *tp = pytime_from_nanoseconds(t);
473
474    if (raise_exc && (res1 < 0 || res2 < 0)) {
475        pytime_overflow();
476        return -1;
477    }
478    return 0;
479}
480
481int
482_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
483{
484    return pytime_fromtimespec(tp, ts, 1);
485}
486#endif
487
488
489#ifndef MS_WINDOWS
490static int
491pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise_exc)
492{
493    static_assert(sizeof(tv->tv_sec) <= sizeof(_PyTime_t),
494                  "timeval.tv_sec is larger than _PyTime_t");
495    _PyTime_t t = (_PyTime_t)tv->tv_sec;
496
497    int res1 = pytime_mul(&t, SEC_TO_NS);
498
499    _PyTime_t usec = (_PyTime_t)tv->tv_usec * US_TO_NS;
500    int res2 = pytime_add(&t, usec);
501
502    *tp = pytime_from_nanoseconds(t);
503
504    if (raise_exc && (res1 < 0 || res2 < 0)) {
505        pytime_overflow();
506        return -1;
507    }
508    return 0;
509}
510
511
512int
513_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
514{
515    return pytime_fromtimeval(tp, tv, 1);
516}
517#endif
518
519
520static int
521pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round,
522                   long unit_to_ns)
523{
524    /* volatile avoids optimization changing how numbers are rounded */
525    volatile double d;
526
527    /* convert to a number of nanoseconds */
528    d = value;
529    d *= (double)unit_to_ns;
530    d = pytime_round(d, round);
531
532    /* See comments in pytime_double_to_denominator */
533    if (!((double)_PyTime_MIN <= d && d < -(double)_PyTime_MIN)) {
534        pytime_time_t_overflow();
535        return -1;
536    }
537    _PyTime_t ns = (_PyTime_t)d;
538
539    *tp = pytime_from_nanoseconds(ns);
540    return 0;
541}
542
543
544static int
545pytime_from_object(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round,
546                   long unit_to_ns)
547{
548    if (PyFloat_Check(obj)) {
549        double d;
550        d = PyFloat_AsDouble(obj);
551        if (Py_IS_NAN(d)) {
552            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
553            return -1;
554        }
555        return pytime_from_double(tp, d, round, unit_to_ns);
556    }
557    else {
558        long long sec = PyLong_AsLongLong(obj);
559        if (sec == -1 && PyErr_Occurred()) {
560            if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
561                pytime_overflow();
562            }
563            return -1;
564        }
565
566        static_assert(sizeof(long long) <= sizeof(_PyTime_t),
567                      "_PyTime_t is smaller than long long");
568        _PyTime_t ns = (_PyTime_t)sec;
569        if (pytime_mul(&ns, unit_to_ns) < 0) {
570            pytime_overflow();
571            return -1;
572        }
573
574        *tp = pytime_from_nanoseconds(ns);
575        return 0;
576    }
577}
578
579
580int
581_PyTime_FromSecondsObject(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
582{
583    return pytime_from_object(tp, obj, round, SEC_TO_NS);
584}
585
586
587int
588_PyTime_FromMillisecondsObject(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
589{
590    return pytime_from_object(tp, obj, round, MS_TO_NS);
591}
592
593
594double
595_PyTime_AsSecondsDouble(_PyTime_t t)
596{
597    /* volatile avoids optimization changing how numbers are rounded */
598    volatile double d;
599
600    _PyTime_t ns = pytime_as_nanoseconds(t);
601    if (ns % SEC_TO_NS == 0) {
602        /* Divide using integers to avoid rounding issues on the integer part.
603           1e-9 cannot be stored exactly in IEEE 64-bit. */
604        _PyTime_t secs = ns / SEC_TO_NS;
605        d = (double)secs;
606    }
607    else {
608        d = (double)ns;
609        d /= 1e9;
610    }
611    return d;
612}
613
614
615PyObject *
616_PyTime_AsNanosecondsObject(_PyTime_t t)
617{
618    _PyTime_t ns =  pytime_as_nanoseconds(t);
619    static_assert(sizeof(long long) >= sizeof(_PyTime_t),
620                  "_PyTime_t is larger than long long");
621    return PyLong_FromLongLong((long long)ns);
622}
623
624
625static _PyTime_t
626pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k)
627{
628    assert(k > 1);
629    if (t >= 0) {
630        // Don't use (t + k - 1) / k to avoid integer overflow
631        // if t is equal to _PyTime_MAX
632        _PyTime_t q = t / k;
633        if (t % k) {
634            q += 1;
635        }
636        return q;
637    }
638    else {
639        // Don't use (t - (k - 1)) / k to avoid integer overflow
640        // if t is equals to _PyTime_MIN.
641        _PyTime_t q = t / k;
642        if (t % k) {
643            q -= 1;
644        }
645        return q;
646    }
647}
648
649
650static _PyTime_t
651pytime_divide(const _PyTime_t t, const _PyTime_t k,
652              const _PyTime_round_t round)
653{
654    assert(k > 1);
655    if (round == _PyTime_ROUND_HALF_EVEN) {
656        _PyTime_t x = t / k;
657        _PyTime_t r = t % k;
658        _PyTime_t abs_r = Py_ABS(r);
659        if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
660            if (t >= 0) {
661                x++;
662            }
663            else {
664                x--;
665            }
666        }
667        return x;
668    }
669    else if (round == _PyTime_ROUND_CEILING) {
670        if (t >= 0) {
671            return pytime_divide_round_up(t, k);
672        }
673        else {
674            return t / k;
675        }
676    }
677    else if (round == _PyTime_ROUND_FLOOR){
678        if (t >= 0) {
679            return t / k;
680        }
681        else {
682            return pytime_divide_round_up(t, k);
683        }
684    }
685    else {
686        assert(round == _PyTime_ROUND_UP);
687        return pytime_divide_round_up(t, k);
688    }
689}
690
691
692// Compute (t / k, t % k) in (pq, pr).
693// Make sure that 0 <= pr < k.
694// Return 0 on success.
695// Return -1 on underflow and store (_PyTime_MIN, 0) in (pq, pr).
696static int
697pytime_divmod(const _PyTime_t t, const _PyTime_t k,
698              _PyTime_t *pq, _PyTime_t *pr)
699{
700    assert(k > 1);
701    _PyTime_t q = t / k;
702    _PyTime_t r = t % k;
703    if (r < 0) {
704        if (q == _PyTime_MIN) {
705            *pq = _PyTime_MIN;
706            *pr = 0;
707            return -1;
708        }
709        r += k;
710        q -= 1;
711    }
712    assert(0 <= r && r < k);
713
714    *pq = q;
715    *pr = r;
716    return 0;
717}
718
719
720_PyTime_t
721_PyTime_AsNanoseconds(_PyTime_t t)
722{
723    return pytime_as_nanoseconds(t);
724}
725
726
727#ifdef MS_WINDOWS
728_PyTime_t
729_PyTime_As100Nanoseconds(_PyTime_t t, _PyTime_round_t round)
730{
731    _PyTime_t ns = pytime_as_nanoseconds(t);
732    return pytime_divide(ns, NS_TO_100NS, round);
733}
734#endif
735
736
737_PyTime_t
738_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
739{
740    _PyTime_t ns = pytime_as_nanoseconds(t);
741    return pytime_divide(ns, NS_TO_US, round);
742}
743
744
745_PyTime_t
746_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
747{
748    _PyTime_t ns = pytime_as_nanoseconds(t);
749    return pytime_divide(ns, NS_TO_MS, round);
750}
751
752
753static int
754pytime_as_timeval(_PyTime_t t, _PyTime_t *ptv_sec, int *ptv_usec,
755                  _PyTime_round_t round)
756{
757    _PyTime_t ns = pytime_as_nanoseconds(t);
758    _PyTime_t us = pytime_divide(ns, US_TO_NS, round);
759
760    _PyTime_t tv_sec, tv_usec;
761    int res = pytime_divmod(us, SEC_TO_US, &tv_sec, &tv_usec);
762    *ptv_sec = tv_sec;
763    *ptv_usec = (int)tv_usec;
764    return res;
765}
766
767
768static int
769pytime_as_timeval_struct(_PyTime_t t, struct timeval *tv,
770                         _PyTime_round_t round, int raise_exc)
771{
772    _PyTime_t tv_sec;
773    int tv_usec;
774    int res = pytime_as_timeval(t, &tv_sec, &tv_usec, round);
775    int res2;
776#ifdef MS_WINDOWS
777    // On Windows, timeval.tv_sec type is long
778    res2 = _PyTime_AsLong(tv_sec, &tv->tv_sec);
779#else
780    res2 = _PyTime_AsTime_t(tv_sec, &tv->tv_sec);
781#endif
782    if (res2 < 0) {
783        tv_usec = 0;
784    }
785    tv->tv_usec = tv_usec;
786
787    if (raise_exc && (res < 0 || res2 < 0)) {
788        pytime_time_t_overflow();
789        return -1;
790    }
791    return 0;
792}
793
794
795int
796_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
797{
798    return pytime_as_timeval_struct(t, tv, round, 1);
799}
800
801
802void
803_PyTime_AsTimeval_clamp(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
804{
805    (void)pytime_as_timeval_struct(t, tv, round, 0);
806}
807
808
809int
810_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
811                        _PyTime_round_t round)
812{
813    _PyTime_t secs;
814    if (pytime_as_timeval(t, &secs, us, round) < 0) {
815        pytime_time_t_overflow();
816        return -1;
817    }
818
819    if (_PyTime_AsTime_t(secs, p_secs) < 0) {
820        pytime_time_t_overflow();
821        return -1;
822    }
823    return 0;
824}
825
826
827#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
828static int
829pytime_as_timespec(_PyTime_t t, struct timespec *ts, int raise_exc)
830{
831    _PyTime_t ns = pytime_as_nanoseconds(t);
832    _PyTime_t tv_sec, tv_nsec;
833    int res = pytime_divmod(ns, SEC_TO_NS, &tv_sec, &tv_nsec);
834
835    int res2 = _PyTime_AsTime_t(tv_sec, &ts->tv_sec);
836    if (res2 < 0) {
837        tv_nsec = 0;
838    }
839    ts->tv_nsec = tv_nsec;
840
841    if (raise_exc && (res < 0 || res2 < 0)) {
842        pytime_time_t_overflow();
843        return -1;
844    }
845    return 0;
846}
847
848void
849_PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts)
850{
851    (void)pytime_as_timespec(t, ts, 0);
852}
853
854int
855_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
856{
857    return pytime_as_timespec(t, ts, 1);
858}
859#endif
860
861
862static int
863py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
864{
865    assert(info == NULL || raise_exc);
866
867#ifdef MS_WINDOWS
868    FILETIME system_time;
869    ULARGE_INTEGER large;
870
871    GetSystemTimeAsFileTime(&system_time);
872    large.u.LowPart = system_time.dwLowDateTime;
873    large.u.HighPart = system_time.dwHighDateTime;
874    /* 11,644,473,600,000,000,000: number of nanoseconds between
875       the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
876       days). */
877    _PyTime_t ns = large.QuadPart * 100 - 11644473600000000000;
878    *tp = pytime_from_nanoseconds(ns);
879    if (info) {
880        DWORD timeAdjustment, timeIncrement;
881        BOOL isTimeAdjustmentDisabled, ok;
882
883        info->implementation = "GetSystemTimeAsFileTime()";
884        info->monotonic = 0;
885        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
886                                     &isTimeAdjustmentDisabled);
887        if (!ok) {
888            PyErr_SetFromWindowsErr(0);
889            return -1;
890        }
891        info->resolution = timeIncrement * 1e-7;
892        info->adjustable = 1;
893    }
894
895#else   /* MS_WINDOWS */
896    int err;
897#if defined(HAVE_CLOCK_GETTIME)
898    struct timespec ts;
899#endif
900
901#if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__)
902    struct timeval tv;
903#endif
904
905#ifdef HAVE_CLOCK_GETTIME
906
907#ifdef HAVE_CLOCK_GETTIME_RUNTIME
908    if (HAVE_CLOCK_GETTIME_RUNTIME) {
909#endif
910
911    err = clock_gettime(CLOCK_REALTIME, &ts);
912    if (err) {
913        if (raise_exc) {
914            PyErr_SetFromErrno(PyExc_OSError);
915        }
916        return -1;
917    }
918    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
919        return -1;
920    }
921
922    if (info) {
923        struct timespec res;
924        info->implementation = "clock_gettime(CLOCK_REALTIME)";
925        info->monotonic = 0;
926        info->adjustable = 1;
927        if (clock_getres(CLOCK_REALTIME, &res) == 0) {
928            info->resolution = (double)res.tv_sec + (double)res.tv_nsec * 1e-9;
929        }
930        else {
931            info->resolution = 1e-9;
932        }
933    }
934
935#ifdef HAVE_CLOCK_GETTIME_RUNTIME
936    }
937    else {
938#endif
939
940#endif
941
942#if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME)
943
944     /* test gettimeofday() */
945    err = gettimeofday(&tv, (struct timezone *)NULL);
946    if (err) {
947        if (raise_exc) {
948            PyErr_SetFromErrno(PyExc_OSError);
949        }
950        return -1;
951    }
952    if (pytime_fromtimeval(tp, &tv, raise_exc) < 0) {
953        return -1;
954    }
955
956    if (info) {
957        info->implementation = "gettimeofday()";
958        info->resolution = 1e-6;
959        info->monotonic = 0;
960        info->adjustable = 1;
961    }
962
963#if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME)
964    } /* end of availibity block */
965#endif
966
967#endif   /* !HAVE_CLOCK_GETTIME */
968#endif   /* !MS_WINDOWS */
969    return 0;
970}
971
972
973_PyTime_t
974_PyTime_GetSystemClock(void)
975{
976    _PyTime_t t;
977    if (py_get_system_clock(&t, NULL, 0) < 0) {
978        // If clock_gettime(CLOCK_REALTIME) or gettimeofday() fails:
979        // silently ignore the failure and return 0.
980        t = 0;
981    }
982    return t;
983}
984
985
986int
987_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
988{
989    return py_get_system_clock(t, info, 1);
990}
991
992
993#ifdef __APPLE__
994static int
995py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise)
996{
997    static mach_timebase_info_data_t timebase;
998    /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
999       fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
1000    (void)mach_timebase_info(&timebase);
1001
1002    /* Sanity check: should never occur in practice */
1003    if (timebase.numer < 1 || timebase.denom < 1) {
1004        if (raise) {
1005            PyErr_SetString(PyExc_RuntimeError,
1006                            "invalid mach_timebase_info");
1007        }
1008        return -1;
1009    }
1010
1011    /* Check that timebase.numer and timebase.denom can be casted to
1012       _PyTime_t. In practice, timebase uses uint32_t, so casting cannot
1013       overflow. At the end, only make sure that the type is uint32_t
1014       (_PyTime_t is 64-bit long). */
1015    static_assert(sizeof(timebase.numer) <= sizeof(_PyTime_t),
1016                  "timebase.numer is larger than _PyTime_t");
1017    static_assert(sizeof(timebase.denom) <= sizeof(_PyTime_t),
1018                  "timebase.denom is larger than _PyTime_t");
1019
1020    /* Make sure that _PyTime_MulDiv(ticks, timebase_numer, timebase_denom)
1021       cannot overflow.
1022
1023       Known time bases:
1024
1025       * (1, 1) on Intel
1026       * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC
1027
1028       None of these time bases can overflow with 64-bit _PyTime_t, but
1029       check for overflow, just in case. */
1030    if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) {
1031        if (raise) {
1032            PyErr_SetString(PyExc_OverflowError,
1033                            "mach_timebase_info is too large");
1034        }
1035        return -1;
1036    }
1037
1038    *pnumer = (_PyTime_t)timebase.numer;
1039    *pdenom = (_PyTime_t)timebase.denom;
1040    return 0;
1041}
1042#endif
1043
1044
1045static int
1046py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1047{
1048    assert(info == NULL || raise_exc);
1049
1050#if defined(MS_WINDOWS)
1051    ULONGLONG ticks = GetTickCount64();
1052    static_assert(sizeof(ticks) <= sizeof(_PyTime_t),
1053                  "ULONGLONG is larger than _PyTime_t");
1054    _PyTime_t t;
1055    if (ticks <= (ULONGLONG)_PyTime_MAX) {
1056        t = (_PyTime_t)ticks;
1057    }
1058    else {
1059        // GetTickCount64() maximum is larger than _PyTime_t maximum:
1060        // ULONGLONG is unsigned, whereas _PyTime_t is signed.
1061        t = _PyTime_MAX;
1062    }
1063
1064    int res = pytime_mul(&t, MS_TO_NS);
1065    *tp = t;
1066
1067    if (raise_exc && res < 0) {
1068        pytime_overflow();
1069        return -1;
1070    }
1071
1072    if (info) {
1073        DWORD timeAdjustment, timeIncrement;
1074        BOOL isTimeAdjustmentDisabled, ok;
1075        info->implementation = "GetTickCount64()";
1076        info->monotonic = 1;
1077        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
1078                                     &isTimeAdjustmentDisabled);
1079        if (!ok) {
1080            PyErr_SetFromWindowsErr(0);
1081            return -1;
1082        }
1083        info->resolution = timeIncrement * 1e-7;
1084        info->adjustable = 0;
1085    }
1086
1087#elif defined(__APPLE__)
1088    static _PyTime_t timebase_numer = 0;
1089    static _PyTime_t timebase_denom = 0;
1090    if (timebase_denom == 0) {
1091        if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise_exc) < 0) {
1092            return -1;
1093        }
1094    }
1095
1096    if (info) {
1097        info->implementation = "mach_absolute_time()";
1098        info->resolution = (double)timebase_numer / (double)timebase_denom * 1e-9;
1099        info->monotonic = 1;
1100        info->adjustable = 0;
1101    }
1102
1103    uint64_t uticks = mach_absolute_time();
1104    // unsigned => signed
1105    assert(uticks <= (uint64_t)_PyTime_MAX);
1106    _PyTime_t ticks = (_PyTime_t)uticks;
1107
1108    _PyTime_t ns = _PyTime_MulDiv(ticks, timebase_numer, timebase_denom);
1109    *tp = pytime_from_nanoseconds(ns);
1110
1111#elif defined(__hpux)
1112    hrtime_t time;
1113
1114    time = gethrtime();
1115    if (time == -1) {
1116        if (raise_exc) {
1117            PyErr_SetFromErrno(PyExc_OSError);
1118        }
1119        return -1;
1120    }
1121
1122    *tp = pytime_from_nanoseconds(time);
1123
1124    if (info) {
1125        info->implementation = "gethrtime()";
1126        info->resolution = 1e-9;
1127        info->monotonic = 1;
1128        info->adjustable = 0;
1129    }
1130
1131#else
1132
1133#ifdef CLOCK_HIGHRES
1134    const clockid_t clk_id = CLOCK_HIGHRES;
1135    const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
1136#else
1137    const clockid_t clk_id = CLOCK_MONOTONIC;
1138    const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
1139#endif
1140
1141    struct timespec ts;
1142    if (clock_gettime(clk_id, &ts) != 0) {
1143        if (raise_exc) {
1144            PyErr_SetFromErrno(PyExc_OSError);
1145            return -1;
1146        }
1147        return -1;
1148    }
1149
1150    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
1151        return -1;
1152    }
1153
1154    if (info) {
1155        info->monotonic = 1;
1156        info->implementation = implementation;
1157        info->adjustable = 0;
1158        struct timespec res;
1159        if (clock_getres(clk_id, &res) != 0) {
1160            PyErr_SetFromErrno(PyExc_OSError);
1161            return -1;
1162        }
1163        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1164    }
1165#endif
1166    return 0;
1167}
1168
1169
1170_PyTime_t
1171_PyTime_GetMonotonicClock(void)
1172{
1173    _PyTime_t t;
1174    if (py_get_monotonic_clock(&t, NULL, 0) < 0) {
1175        // If mach_timebase_info(), clock_gettime() or gethrtime() fails:
1176        // silently ignore the failure and return 0.
1177        t = 0;
1178    }
1179    return t;
1180}
1181
1182
1183int
1184_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1185{
1186    return py_get_monotonic_clock(tp, info, 1);
1187}
1188
1189
1190#ifdef MS_WINDOWS
1191static int
1192py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise)
1193{
1194    LONGLONG frequency;
1195
1196    LARGE_INTEGER freq;
1197    // Since Windows XP, the function cannot fail.
1198    (void)QueryPerformanceFrequency(&freq);
1199    frequency = freq.QuadPart;
1200
1201    // Since Windows XP, frequency cannot be zero.
1202    assert(frequency >= 1);
1203
1204    /* Make also sure that (ticks * SEC_TO_NS) cannot overflow in
1205       _PyTime_MulDiv(), with ticks < frequency.
1206
1207       Known QueryPerformanceFrequency() values:
1208
1209       * 10,000,000 (10 MHz): 100 ns resolution
1210       * 3,579,545 Hz (3.6 MHz): 279 ns resolution
1211
1212       None of these frequencies can overflow with 64-bit _PyTime_t, but
1213       check for integer overflow just in case. */
1214    if (frequency > _PyTime_MAX / SEC_TO_NS) {
1215        if (raise) {
1216            PyErr_SetString(PyExc_OverflowError,
1217                            "QueryPerformanceFrequency is too large");
1218        }
1219        return -1;
1220    }
1221
1222    *pfrequency = frequency;
1223    return 0;
1224}
1225
1226
1227static int
1228py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1229{
1230    assert(info == NULL || raise_exc);
1231
1232    static LONGLONG frequency = 0;
1233    if (frequency == 0) {
1234        if (py_win_perf_counter_frequency(&frequency, raise_exc) < 0) {
1235            return -1;
1236        }
1237    }
1238
1239    if (info) {
1240        info->implementation = "QueryPerformanceCounter()";
1241        info->resolution = 1.0 / (double)frequency;
1242        info->monotonic = 1;
1243        info->adjustable = 0;
1244    }
1245
1246    LARGE_INTEGER now;
1247    QueryPerformanceCounter(&now);
1248    LONGLONG ticksll = now.QuadPart;
1249
1250    /* Make sure that casting LONGLONG to _PyTime_t cannot overflow,
1251       both types are signed */
1252    _PyTime_t ticks;
1253    static_assert(sizeof(ticksll) <= sizeof(ticks),
1254                  "LONGLONG is larger than _PyTime_t");
1255    ticks = (_PyTime_t)ticksll;
1256
1257    _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency);
1258    *tp = pytime_from_nanoseconds(ns);
1259    return 0;
1260}
1261#endif  // MS_WINDOWS
1262
1263
1264int
1265_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
1266{
1267#ifdef MS_WINDOWS
1268    return py_get_win_perf_counter(t, info, 1);
1269#else
1270    return _PyTime_GetMonotonicClockWithInfo(t, info);
1271#endif
1272}
1273
1274
1275_PyTime_t
1276_PyTime_GetPerfCounter(void)
1277{
1278    _PyTime_t t;
1279    int res;
1280#ifdef MS_WINDOWS
1281    res = py_get_win_perf_counter(&t, NULL, 0);
1282#else
1283    res = py_get_monotonic_clock(&t, NULL, 0);
1284#endif
1285    if (res  < 0) {
1286        // If py_win_perf_counter_frequency() or py_get_monotonic_clock()
1287        // fails: silently ignore the failure and return 0.
1288        t = 0;
1289    }
1290    return t;
1291}
1292
1293
1294int
1295_PyTime_localtime(time_t t, struct tm *tm)
1296{
1297#ifdef MS_WINDOWS
1298    int error;
1299
1300    error = localtime_s(tm, &t);
1301    if (error != 0) {
1302        errno = error;
1303        PyErr_SetFromErrno(PyExc_OSError);
1304        return -1;
1305    }
1306    return 0;
1307#else /* !MS_WINDOWS */
1308
1309#if defined(_AIX) && (SIZEOF_TIME_T < 8)
1310    /* bpo-34373: AIX does not return NULL if t is too small or too large */
1311    if (t < -2145916800 /* 1902-01-01 */
1312       || t > 2145916800 /* 2038-01-01 */) {
1313        errno = EINVAL;
1314        PyErr_SetString(PyExc_OverflowError,
1315                        "localtime argument out of range");
1316        return -1;
1317    }
1318#endif
1319
1320    errno = 0;
1321    if (localtime_r(&t, tm) == NULL) {
1322        if (errno == 0) {
1323            errno = EINVAL;
1324        }
1325        PyErr_SetFromErrno(PyExc_OSError);
1326        return -1;
1327    }
1328    return 0;
1329#endif /* MS_WINDOWS */
1330}
1331
1332
1333int
1334_PyTime_gmtime(time_t t, struct tm *tm)
1335{
1336#ifdef MS_WINDOWS
1337    int error;
1338
1339    error = gmtime_s(tm, &t);
1340    if (error != 0) {
1341        errno = error;
1342        PyErr_SetFromErrno(PyExc_OSError);
1343        return -1;
1344    }
1345    return 0;
1346#else /* !MS_WINDOWS */
1347    if (gmtime_r(&t, tm) == NULL) {
1348#ifdef EINVAL
1349        if (errno == 0) {
1350            errno = EINVAL;
1351        }
1352#endif
1353        PyErr_SetFromErrno(PyExc_OSError);
1354        return -1;
1355    }
1356    return 0;
1357#endif /* MS_WINDOWS */
1358}
1359
1360
1361_PyTime_t
1362_PyDeadline_Init(_PyTime_t timeout)
1363{
1364    _PyTime_t now = _PyTime_GetMonotonicClock();
1365    return _PyTime_Add(now, timeout);
1366}
1367
1368
1369_PyTime_t
1370_PyDeadline_Get(_PyTime_t deadline)
1371{
1372    _PyTime_t now = _PyTime_GetMonotonicClock();
1373    return deadline - now;
1374}
1375