Coverage Report

Created: 2025-07-04 06:49

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