Coverage Report

Created: 2025-10-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/pytime.c
Line
Count
Source
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
6.67k
#define SEC_TO_MS 1000
27
28
/* To microseconds (10^-6) */
29
6.67k
#define MS_TO_US 1000
30
0
#define SEC_TO_US (SEC_TO_MS * MS_TO_US)
31
32
/* To nanoseconds (10^-9) */
33
9.83k
#define US_TO_NS 1000
34
6.67k
#define MS_TO_NS (MS_TO_US * US_TO_NS)
35
6.67k
#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
3.15k
{
144
3.15k
    if (b != 0) {
145
3.15k
        assert(b > 0);
146
3.15k
        return ((a < PyTime_MIN / b) || (PyTime_MAX / b < a));
147
3.15k
    }
148
0
    else {
149
0
        return 0;
150
0
    }
151
3.15k
}
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
3.15k
{
158
3.15k
    assert(k >= 0);
159
3.15k
    if (pytime_mul_check_overflow(*t, k)) {
160
0
        *t = (*t >= 0) ? PyTime_MAX : PyTime_MIN;
161
0
        return -1;
162
0
    }
163
3.15k
    else {
164
3.15k
        *t *= k;
165
3.15k
        return 0;
166
3.15k
    }
167
3.15k
}
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
3.15k
{
174
3.15k
    (void)pytime_mul(&t, k);
175
3.15k
    return t;
176
3.15k
}
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
15.7k
{
227
15.7k
#if SIZEOF_TIME_T == SIZEOF_LONG_LONG
228
15.7k
    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
15.7k
}
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 (PyIndex_Check(obj)) {
372
0
        *sec = _PyLong_AsTime_t(obj);
373
0
        *numerator = 0;
374
0
        if (*sec == (time_t)-1 && PyErr_Occurred()) {
375
0
            return -1;
376
0
        }
377
0
        return 0;
378
0
    }
379
0
    else {
380
0
        double d = PyFloat_AsDouble(obj);
381
0
        if (d == -1 && PyErr_Occurred()) {
382
0
            *numerator = 0;
383
0
            return -1;
384
0
        }
385
0
        if (isnan(d)) {
386
0
            *numerator = 0;
387
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
388
0
            return -1;
389
0
        }
390
0
        return pytime_double_to_denominator(d, sec, numerator,
391
0
                                            denominator, round);
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 (PyIndex_Check(obj)) {
400
0
        *sec = _PyLong_AsTime_t(obj);
401
0
        if (*sec == (time_t)-1 && PyErr_Occurred()) {
402
0
            return -1;
403
0
        }
404
0
        return 0;
405
0
    }
406
0
    else {
407
0
        double intpart;
408
        /* volatile avoids optimization changing how numbers are rounded */
409
0
        volatile double d;
410
411
0
        d = PyFloat_AsDouble(obj);
412
0
        if (d == -1 && PyErr_Occurred()) {
413
0
            return -1;
414
0
        }
415
0
        if (isnan(d)) {
416
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
417
0
            return -1;
418
0
        }
419
420
0
        d = pytime_round(d, round);
421
0
        (void)modf(d, &intpart);
422
423
        /* See comments in pytime_double_to_denominator */
424
0
        if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
425
0
            pytime_time_t_overflow();
426
0
            return -1;
427
0
        }
428
0
        *sec = (time_t)intpart;
429
0
        return 0;
430
0
    }
431
0
}
432
433
434
int
435
_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
436
                         _PyTime_round_t round)
437
0
{
438
0
    return pytime_object_to_denominator(obj, sec, nsec, SEC_TO_NS, round);
439
0
}
440
441
442
int
443
_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
444
                        _PyTime_round_t round)
445
0
{
446
0
    return pytime_object_to_denominator(obj, sec, usec, SEC_TO_US, round);
447
0
}
448
449
450
PyTime_t
451
_PyTime_FromSeconds(int seconds)
452
6.66k
{
453
    /* ensure that integer overflow cannot happen, int type should have 32
454
       bits, whereas PyTime_t type has at least 64 bits (SEC_TO_NS takes 30
455
       bits). */
456
6.66k
    static_assert(INT_MAX <= PyTime_MAX / SEC_TO_NS, "PyTime_t overflow");
457
6.66k
    static_assert(INT_MIN >= PyTime_MIN / SEC_TO_NS, "PyTime_t underflow");
458
459
6.66k
    PyTime_t t = (PyTime_t)seconds;
460
6.66k
    assert((t >= 0 && t <= PyTime_MAX / SEC_TO_NS)
461
6.66k
           || (t < 0 && t >= PyTime_MIN / SEC_TO_NS));
462
6.66k
    t *= SEC_TO_NS;
463
6.66k
    return t;
464
6.66k
}
465
466
467
PyTime_t
468
_PyTime_FromMicrosecondsClamp(PyTime_t us)
469
3.15k
{
470
3.15k
    PyTime_t ns = _PyTime_Mul(us, US_TO_NS);
471
3.15k
    return ns;
472
3.15k
}
473
474
475
int
476
_PyTime_FromLong(PyTime_t *tp, PyObject *obj)
477
0
{
478
0
    if (!PyLong_Check(obj)) {
479
0
        PyErr_Format(PyExc_TypeError, "expect int, got %s",
480
0
                     Py_TYPE(obj)->tp_name);
481
0
        return -1;
482
0
    }
483
484
0
    static_assert(sizeof(long long) == sizeof(PyTime_t),
485
0
                  "PyTime_t is not long long");
486
0
    long long nsec = PyLong_AsLongLong(obj);
487
0
    if (nsec == -1 && PyErr_Occurred()) {
488
0
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
489
0
            pytime_overflow();
490
0
        }
491
0
        return -1;
492
0
    }
493
494
0
    PyTime_t t = (PyTime_t)nsec;
495
0
    *tp = t;
496
0
    return 0;
497
0
}
498
499
500
#ifdef HAVE_CLOCK_GETTIME
501
static int
502
pytime_fromtimespec(PyTime_t *tp, const struct timespec *ts, int raise_exc)
503
0
{
504
0
    PyTime_t t, tv_nsec;
505
506
0
    static_assert(sizeof(ts->tv_sec) <= sizeof(PyTime_t),
507
0
                  "timespec.tv_sec is larger than PyTime_t");
508
0
    t = (PyTime_t)ts->tv_sec;
509
510
0
    int res1 = pytime_mul(&t, SEC_TO_NS);
511
512
0
    tv_nsec = ts->tv_nsec;
513
0
    int res2 = pytime_add(&t, tv_nsec);
514
515
0
    *tp = t;
516
517
0
    if (raise_exc && (res1 < 0 || res2 < 0)) {
518
0
        pytime_overflow();
519
0
        return -1;
520
0
    }
521
0
    return 0;
522
0
}
523
524
int
525
_PyTime_FromTimespec(PyTime_t *tp, const struct timespec *ts)
526
0
{
527
0
    return pytime_fromtimespec(tp, ts, 1);
528
0
}
529
#endif
530
531
532
#ifndef MS_WINDOWS
533
static int
534
pytime_fromtimeval(PyTime_t *tp, struct timeval *tv, int raise_exc)
535
0
{
536
0
    static_assert(sizeof(tv->tv_sec) <= sizeof(PyTime_t),
537
0
                  "timeval.tv_sec is larger than PyTime_t");
538
0
    PyTime_t t = (PyTime_t)tv->tv_sec;
539
540
0
    int res1 = pytime_mul(&t, SEC_TO_NS);
541
542
0
    PyTime_t usec = (PyTime_t)tv->tv_usec * US_TO_NS;
543
0
    int res2 = pytime_add(&t, usec);
544
545
0
    *tp = t;
546
547
0
    if (raise_exc && (res1 < 0 || res2 < 0)) {
548
0
        pytime_overflow();
549
0
        return -1;
550
0
    }
551
0
    return 0;
552
0
}
553
554
555
int
556
_PyTime_FromTimeval(PyTime_t *tp, struct timeval *tv)
557
0
{
558
0
    return pytime_fromtimeval(tp, tv, 1);
559
0
}
560
#endif
561
562
563
static int
564
pytime_from_double(PyTime_t *tp, double value, _PyTime_round_t round,
565
                   long unit_to_ns)
566
0
{
567
    /* volatile avoids optimization changing how numbers are rounded */
568
0
    volatile double d;
569
570
    /* convert to a number of nanoseconds */
571
0
    d = value;
572
0
    d *= (double)unit_to_ns;
573
0
    d = pytime_round(d, round);
574
575
    /* See comments in pytime_double_to_denominator */
576
0
    if (!((double)PyTime_MIN <= d && d < -(double)PyTime_MIN)) {
577
0
        pytime_time_t_overflow();
578
0
        *tp = 0;
579
0
        return -1;
580
0
    }
581
0
    PyTime_t ns = (PyTime_t)d;
582
583
0
    *tp = ns;
584
0
    return 0;
585
0
}
586
587
588
static int
589
pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round,
590
                   long unit_to_ns)
591
0
{
592
0
    if (PyIndex_Check(obj)) {
593
0
        long long sec = PyLong_AsLongLong(obj);
594
0
        if (sec == -1 && PyErr_Occurred()) {
595
0
            if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
596
0
                pytime_overflow();
597
0
            }
598
0
            return -1;
599
0
        }
600
601
0
        static_assert(sizeof(long long) <= sizeof(PyTime_t),
602
0
                    "PyTime_t is smaller than long long");
603
0
        PyTime_t ns = (PyTime_t)sec;
604
0
        if (pytime_mul(&ns, unit_to_ns) < 0) {
605
0
            pytime_overflow();
606
0
            return -1;
607
0
        }
608
609
0
        *tp = ns;
610
0
        return 0;
611
0
    }
612
0
    else {
613
0
        double d;
614
0
        d = PyFloat_AsDouble(obj);
615
0
        if (d == -1 && PyErr_Occurred()) {
616
0
            return -1;
617
0
        }
618
0
        if (isnan(d)) {
619
0
            PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
620
0
            return -1;
621
0
        }
622
0
        return pytime_from_double(tp, d, round, unit_to_ns);
623
0
    }
624
0
}
625
626
627
int
628
_PyTime_FromSecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
629
0
{
630
0
    return pytime_from_object(tp, obj, round, SEC_TO_NS);
631
0
}
632
633
634
int
635
_PyTime_FromMillisecondsObject(PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
636
0
{
637
0
    return pytime_from_object(tp, obj, round, MS_TO_NS);
638
0
}
639
640
641
double
642
PyTime_AsSecondsDouble(PyTime_t ns)
643
16
{
644
    /* volatile avoids optimization changing how numbers are rounded */
645
16
    volatile double d;
646
647
16
    if (ns % SEC_TO_NS == 0) {
648
        /* Divide using integers to avoid rounding issues on the integer part.
649
           1e-9 cannot be stored exactly in IEEE 64-bit. */
650
0
        PyTime_t secs = ns / SEC_TO_NS;
651
0
        d = (double)secs;
652
0
    }
653
16
    else {
654
16
        d = (double)ns;
655
16
        d /= 1e9;
656
16
    }
657
16
    return d;
658
16
}
659
660
661
PyObject *
662
_PyTime_AsLong(PyTime_t ns)
663
0
{
664
0
    static_assert(sizeof(long long) >= sizeof(PyTime_t),
665
0
                  "PyTime_t is larger than long long");
666
0
    return PyLong_FromLongLong((long long)ns);
667
0
}
668
669
int
670
_PyTime_FromSecondsDouble(double seconds, _PyTime_round_t round, PyTime_t *result)
671
0
{
672
0
    return pytime_from_double(result, seconds, round, SEC_TO_NS);
673
0
}
674
675
676
static PyTime_t
677
pytime_divide_round_up(const PyTime_t t, const PyTime_t k)
678
0
{
679
0
    assert(k > 1);
680
0
    if (t >= 0) {
681
        // Don't use (t + k - 1) / k to avoid integer overflow
682
        // if t is equal to PyTime_MAX
683
0
        PyTime_t q = t / k;
684
0
        if (t % k) {
685
0
            q += 1;
686
0
        }
687
0
        return q;
688
0
    }
689
0
    else {
690
        // Don't use (t - (k - 1)) / k to avoid integer overflow
691
        // if t is equals to PyTime_MIN.
692
0
        PyTime_t q = t / k;
693
0
        if (t % k) {
694
0
            q -= 1;
695
0
        }
696
0
        return q;
697
0
    }
698
0
}
699
700
701
static PyTime_t
702
pytime_divide(const PyTime_t t, const PyTime_t k,
703
              const _PyTime_round_t round)
704
0
{
705
0
    assert(k > 1);
706
0
    if (round == _PyTime_ROUND_HALF_EVEN) {
707
0
        PyTime_t x = t / k;
708
0
        PyTime_t r = t % k;
709
0
        PyTime_t abs_r = Py_ABS(r);
710
0
        if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
711
0
            if (t >= 0) {
712
0
                x++;
713
0
            }
714
0
            else {
715
0
                x--;
716
0
            }
717
0
        }
718
0
        return x;
719
0
    }
720
0
    else if (round == _PyTime_ROUND_CEILING) {
721
0
        if (t >= 0) {
722
0
            return pytime_divide_round_up(t, k);
723
0
        }
724
0
        else {
725
0
            return t / k;
726
0
        }
727
0
    }
728
0
    else if (round == _PyTime_ROUND_FLOOR){
729
0
        if (t >= 0) {
730
0
            return t / k;
731
0
        }
732
0
        else {
733
0
            return pytime_divide_round_up(t, k);
734
0
        }
735
0
    }
736
0
    else {
737
0
        assert(round == _PyTime_ROUND_UP);
738
0
        return pytime_divide_round_up(t, k);
739
0
    }
740
0
}
741
742
743
// Compute (t / k, t % k) in (pq, pr).
744
// Make sure that 0 <= pr < k.
745
// Return 0 on success.
746
// Return -1 on underflow and store (PyTime_MIN, 0) in (pq, pr).
747
static int
748
pytime_divmod(const PyTime_t t, const PyTime_t k,
749
              PyTime_t *pq, PyTime_t *pr)
750
0
{
751
0
    assert(k > 1);
752
0
    PyTime_t q = t / k;
753
0
    PyTime_t r = t % k;
754
0
    if (r < 0) {
755
0
        if (q == PyTime_MIN) {
756
0
            *pq = PyTime_MIN;
757
0
            *pr = 0;
758
0
            return -1;
759
0
        }
760
0
        r += k;
761
0
        q -= 1;
762
0
    }
763
0
    assert(0 <= r && r < k);
764
765
0
    *pq = q;
766
0
    *pr = r;
767
0
    return 0;
768
0
}
769
770
771
#ifdef MS_WINDOWS
772
PyTime_t
773
_PyTime_As100Nanoseconds(PyTime_t ns, _PyTime_round_t round)
774
{
775
    return pytime_divide(ns, NS_TO_100NS, round);
776
}
777
#endif
778
779
780
PyTime_t
781
_PyTime_AsMicroseconds(PyTime_t ns, _PyTime_round_t round)
782
0
{
783
0
    return pytime_divide(ns, NS_TO_US, round);
784
0
}
785
786
787
PyTime_t
788
_PyTime_AsMilliseconds(PyTime_t ns, _PyTime_round_t round)
789
0
{
790
0
    return pytime_divide(ns, NS_TO_MS, round);
791
0
}
792
793
794
static int
795
pytime_as_timeval(PyTime_t ns, PyTime_t *ptv_sec, int *ptv_usec,
796
                  _PyTime_round_t round)
797
0
{
798
0
    PyTime_t us = pytime_divide(ns, US_TO_NS, round);
799
800
0
    PyTime_t tv_sec, tv_usec;
801
0
    int res = pytime_divmod(us, SEC_TO_US, &tv_sec, &tv_usec);
802
0
    *ptv_sec = tv_sec;
803
0
    *ptv_usec = (int)tv_usec;
804
0
    return res;
805
0
}
806
807
808
static int
809
pytime_as_timeval_struct(PyTime_t t, struct timeval *tv,
810
                         _PyTime_round_t round, int raise_exc)
811
0
{
812
0
    PyTime_t tv_sec;
813
0
    int tv_usec;
814
0
    int res = pytime_as_timeval(t, &tv_sec, &tv_usec, round);
815
0
    int res2;
816
#ifdef MS_WINDOWS
817
    // On Windows, timeval.tv_sec type is long
818
    res2 = _PyTime_AsCLong(tv_sec, &tv->tv_sec);
819
#else
820
0
    res2 = _PyTime_AsTime_t(tv_sec, &tv->tv_sec);
821
0
#endif
822
0
    if (res2 < 0) {
823
0
        tv_usec = 0;
824
0
    }
825
0
    tv->tv_usec = tv_usec;
826
827
0
    if (raise_exc && (res < 0 || res2 < 0)) {
828
0
        pytime_time_t_overflow();
829
0
        return -1;
830
0
    }
831
0
    return 0;
832
0
}
833
834
835
int
836
_PyTime_AsTimeval(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
837
0
{
838
0
    return pytime_as_timeval_struct(t, tv, round, 1);
839
0
}
840
841
842
void
843
_PyTime_AsTimeval_clamp(PyTime_t t, struct timeval *tv, _PyTime_round_t round)
844
0
{
845
0
    (void)pytime_as_timeval_struct(t, tv, round, 0);
846
0
}
847
848
849
int
850
_PyTime_AsTimevalTime_t(PyTime_t t, time_t *p_secs, int *us,
851
                        _PyTime_round_t round)
852
0
{
853
0
    PyTime_t secs;
854
0
    if (pytime_as_timeval(t, &secs, us, round) < 0) {
855
0
        pytime_time_t_overflow();
856
0
        return -1;
857
0
    }
858
859
0
    if (_PyTime_AsTime_t(secs, p_secs) < 0) {
860
0
        pytime_time_t_overflow();
861
0
        return -1;
862
0
    }
863
0
    return 0;
864
0
}
865
866
867
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
868
static int
869
pytime_as_timespec(PyTime_t ns, struct timespec *ts, int raise_exc)
870
0
{
871
0
    PyTime_t tv_sec, tv_nsec;
872
0
    int res = pytime_divmod(ns, SEC_TO_NS, &tv_sec, &tv_nsec);
873
874
0
    int res2 = _PyTime_AsTime_t(tv_sec, &ts->tv_sec);
875
0
    if (res2 < 0) {
876
0
        tv_nsec = 0;
877
0
    }
878
0
    ts->tv_nsec = tv_nsec;
879
880
0
    if (raise_exc && (res < 0 || res2 < 0)) {
881
0
        pytime_time_t_overflow();
882
0
        return -1;
883
0
    }
884
0
    return 0;
885
0
}
886
887
void
888
_PyTime_AsTimespec_clamp(PyTime_t t, struct timespec *ts)
889
0
{
890
0
    (void)pytime_as_timespec(t, ts, 0);
891
0
}
892
893
int
894
_PyTime_AsTimespec(PyTime_t t, struct timespec *ts)
895
0
{
896
0
    return pytime_as_timespec(t, ts, 1);
897
0
}
898
#endif
899
900
901
// N.B. If raise_exc=0, this may be called without a thread state.
902
static int
903
py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
904
0
{
905
0
    assert(info == NULL || raise_exc);
906
0
    if (raise_exc) {
907
        // raise_exc requires to hold a thread state
908
0
        _Py_AssertHoldsTstate();
909
0
    }
910
911
#ifdef MS_WINDOWS
912
    FILETIME system_time;
913
    ULARGE_INTEGER large;
914
915
    GetSystemTimePreciseAsFileTime(&system_time);
916
    large.u.LowPart = system_time.dwLowDateTime;
917
    large.u.HighPart = system_time.dwHighDateTime;
918
    /* 11,644,473,600,000,000,000: number of nanoseconds between
919
       the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
920
       days). */
921
    PyTime_t ns = (large.QuadPart - 116444736000000000) * 100;
922
    *tp = ns;
923
    if (info) {
924
        // GetSystemTimePreciseAsFileTime() is implemented using
925
        // QueryPerformanceCounter() internally.
926
        info->implementation = "GetSystemTimePreciseAsFileTime()";
927
        info->monotonic = 0;
928
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
929
        info->adjustable = 1;
930
    }
931
932
#else   /* MS_WINDOWS */
933
0
    int err;
934
0
#if defined(HAVE_CLOCK_GETTIME)
935
0
    struct timespec ts;
936
0
#endif
937
938
#if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__)
939
    struct timeval tv;
940
#endif
941
942
0
#ifdef HAVE_CLOCK_GETTIME
943
944
#ifdef HAVE_CLOCK_GETTIME_RUNTIME
945
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
946
#endif
947
948
0
    err = clock_gettime(CLOCK_REALTIME, &ts);
949
0
    if (err) {
950
0
        if (raise_exc) {
951
0
            PyErr_SetFromErrno(PyExc_OSError);
952
0
        }
953
0
        return -1;
954
0
    }
955
0
    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
956
0
        return -1;
957
0
    }
958
959
0
    if (info) {
960
0
        struct timespec res;
961
0
        info->implementation = "clock_gettime(CLOCK_REALTIME)";
962
0
        info->monotonic = 0;
963
0
        info->adjustable = 1;
964
0
        if (clock_getres(CLOCK_REALTIME, &res) == 0) {
965
0
            info->resolution = (double)res.tv_sec + (double)res.tv_nsec * 1e-9;
966
0
        }
967
0
        else {
968
0
            info->resolution = 1e-9;
969
0
        }
970
0
    }
971
972
#ifdef HAVE_CLOCK_GETTIME_RUNTIME
973
    }
974
    else {
975
#endif
976
977
0
#endif
978
979
#if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME)
980
981
     /* test gettimeofday() */
982
    err = gettimeofday(&tv, (struct timezone *)NULL);
983
    if (err) {
984
        if (raise_exc) {
985
            PyErr_SetFromErrno(PyExc_OSError);
986
        }
987
        return -1;
988
    }
989
    if (pytime_fromtimeval(tp, &tv, raise_exc) < 0) {
990
        return -1;
991
    }
992
993
    if (info) {
994
        info->implementation = "gettimeofday()";
995
        info->resolution = 1e-6;
996
        info->monotonic = 0;
997
        info->adjustable = 1;
998
    }
999
1000
#if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME)
1001
    } /* end of availability block */
1002
#endif
1003
1004
#endif   /* !HAVE_CLOCK_GETTIME */
1005
0
#endif   /* !MS_WINDOWS */
1006
0
    return 0;
1007
0
}
1008
1009
1010
int
1011
PyTime_Time(PyTime_t *result)
1012
0
{
1013
0
    if (py_get_system_clock(result, NULL, 1) < 0) {
1014
0
        *result = 0;
1015
0
        return -1;
1016
0
    }
1017
0
    return 0;
1018
0
}
1019
1020
1021
int
1022
PyTime_TimeRaw(PyTime_t *result)
1023
0
{
1024
0
    if (py_get_system_clock(result, NULL, 0) < 0) {
1025
0
        *result = 0;
1026
0
        return -1;
1027
0
    }
1028
0
    return 0;
1029
0
}
1030
1031
1032
int
1033
_PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info)
1034
0
{
1035
0
    return py_get_system_clock(t, info, 1);
1036
0
}
1037
1038
1039
#ifdef MS_WINDOWS
1040
static PyStatus
1041
py_win_perf_counter_frequency(_PyTimeFraction *base)
1042
{
1043
    LARGE_INTEGER freq;
1044
    // Since Windows XP, the function cannot fail.
1045
    (void)QueryPerformanceFrequency(&freq);
1046
    LONGLONG frequency = freq.QuadPart;
1047
1048
    // Since Windows XP, frequency cannot be zero.
1049
    assert(frequency >= 1);
1050
1051
    Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(frequency));
1052
    PyTime_t denom = (PyTime_t)frequency;
1053
1054
    // Known QueryPerformanceFrequency() values:
1055
    //
1056
    // * 10,000,000 (10 MHz): 100 ns resolution
1057
    // * 3,579,545 Hz (3.6 MHz): 279 ns resolution
1058
    if (_PyTimeFraction_Set(base, SEC_TO_NS, denom) < 0) {
1059
        return _PyStatus_ERR("invalid QueryPerformanceFrequency");
1060
    }
1061
    return PyStatus_Ok();
1062
}
1063
1064
1065
// N.B. If raise_exc=0, this may be called without the GIL.
1066
static int
1067
py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1068
{
1069
    assert(info == NULL || raise_exc);
1070
1071
    if (info) {
1072
        info->implementation = "QueryPerformanceCounter()";
1073
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
1074
        info->monotonic = 1;
1075
        info->adjustable = 0;
1076
    }
1077
1078
    LARGE_INTEGER now;
1079
    QueryPerformanceCounter(&now);
1080
    LONGLONG ticksll = now.QuadPart;
1081
1082
    /* Make sure that casting LONGLONG to PyTime_t cannot overflow,
1083
       both types are signed */
1084
    PyTime_t ticks;
1085
    static_assert(sizeof(ticksll) <= sizeof(ticks),
1086
                  "LONGLONG is larger than PyTime_t");
1087
    ticks = (PyTime_t)ticksll;
1088
1089
    *tp = _PyTimeFraction_Mul(ticks, &_PyRuntime.time.base);
1090
    return 0;
1091
}
1092
#endif  // MS_WINDOWS
1093
1094
1095
#ifdef __APPLE__
1096
static PyStatus
1097
py_mach_timebase_info(_PyTimeFraction *base)
1098
{
1099
    mach_timebase_info_data_t timebase;
1100
    // According to the Technical Q&A QA1398, mach_timebase_info() cannot
1101
    // fail: https://developer.apple.com/library/mac/#qa/qa1398/
1102
    (void)mach_timebase_info(&timebase);
1103
1104
    // Check that timebase.numer and timebase.denom can be casted to
1105
    // PyTime_t. In practice, timebase uses uint32_t, so casting cannot
1106
    // overflow. At the end, only make sure that the type is uint32_t
1107
    // (PyTime_t is 64-bit long).
1108
    Py_BUILD_ASSERT(sizeof(timebase.numer) <= sizeof(PyTime_t));
1109
    Py_BUILD_ASSERT(sizeof(timebase.denom) <= sizeof(PyTime_t));
1110
    PyTime_t numer = (PyTime_t)timebase.numer;
1111
    PyTime_t denom = (PyTime_t)timebase.denom;
1112
1113
    // Known time bases:
1114
    //
1115
    // * (1, 1) on Intel: 1 ns
1116
    // * (1000000000, 33333335) on PowerPC: ~30 ns
1117
    // * (1000000000, 25000000) on PowerPC: 40 ns
1118
    if (_PyTimeFraction_Set(base, numer, denom) < 0) {
1119
        return _PyStatus_ERR("invalid mach_timebase_info");
1120
    }
1121
    return PyStatus_Ok();
1122
}
1123
#endif
1124
1125
PyStatus
1126
_PyTime_Init(struct _Py_time_runtime_state *state)
1127
16
{
1128
#ifdef MS_WINDOWS
1129
    return py_win_perf_counter_frequency(&state->base);
1130
#elif defined(__APPLE__)
1131
    return py_mach_timebase_info(&state->base);
1132
#else
1133
16
    return PyStatus_Ok();
1134
16
#endif
1135
16
}
1136
1137
// N.B. If raise_exc=0, this may be called without a thread state.
1138
static int
1139
py_get_monotonic_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1140
0
{
1141
0
    assert(info == NULL || raise_exc);
1142
0
    if (raise_exc) {
1143
        // raise_exc requires to hold a thread state
1144
0
        _Py_AssertHoldsTstate();
1145
0
    }
1146
1147
#if defined(MS_WINDOWS)
1148
    if (py_get_win_perf_counter(tp, info, raise_exc) < 0) {
1149
        return -1;
1150
    }
1151
#elif defined(__APPLE__)
1152
    if (info) {
1153
        info->implementation = "mach_absolute_time()";
1154
        info->resolution = _PyTimeFraction_Resolution(&_PyRuntime.time.base);
1155
        info->monotonic = 1;
1156
        info->adjustable = 0;
1157
    }
1158
1159
    uint64_t uticks = mach_absolute_time();
1160
    // unsigned => signed
1161
    assert(uticks <= (uint64_t)PyTime_MAX);
1162
    PyTime_t ticks = (PyTime_t)uticks;
1163
1164
    PyTime_t ns = _PyTimeFraction_Mul(ticks, &_PyRuntime.time.base);
1165
    *tp = ns;
1166
1167
#elif defined(__hpux)
1168
    hrtime_t time = gethrtime();
1169
    if (time == -1) {
1170
        if (raise_exc) {
1171
            PyErr_SetFromErrno(PyExc_OSError);
1172
        }
1173
        return -1;
1174
    }
1175
1176
    *tp = time;
1177
1178
    if (info) {
1179
        info->implementation = "gethrtime()";
1180
        info->resolution = 1e-9;
1181
        info->monotonic = 1;
1182
        info->adjustable = 0;
1183
    }
1184
1185
#else
1186
1187
#ifdef CLOCK_HIGHRES
1188
    const clockid_t clk_id = CLOCK_HIGHRES;
1189
    const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
1190
#else
1191
0
    const clockid_t clk_id = CLOCK_MONOTONIC;
1192
0
    const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
1193
0
#endif
1194
1195
0
    struct timespec ts;
1196
0
    if (clock_gettime(clk_id, &ts) != 0) {
1197
0
        if (raise_exc) {
1198
0
            PyErr_SetFromErrno(PyExc_OSError);
1199
0
            return -1;
1200
0
        }
1201
0
        return -1;
1202
0
    }
1203
1204
0
    if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) {
1205
0
        return -1;
1206
0
    }
1207
1208
0
    if (info) {
1209
0
        info->monotonic = 1;
1210
0
        info->implementation = implementation;
1211
0
        info->adjustable = 0;
1212
0
        struct timespec res;
1213
0
        if (clock_getres(clk_id, &res) != 0) {
1214
0
            PyErr_SetFromErrno(PyExc_OSError);
1215
0
            return -1;
1216
0
        }
1217
0
        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1218
0
    }
1219
0
#endif
1220
0
    return 0;
1221
0
}
1222
1223
1224
int
1225
PyTime_Monotonic(PyTime_t *result)
1226
0
{
1227
0
    if (py_get_monotonic_clock(result, NULL, 1) < 0) {
1228
0
        *result = 0;
1229
0
        return -1;
1230
0
    }
1231
0
    return 0;
1232
0
}
1233
1234
1235
int
1236
PyTime_MonotonicRaw(PyTime_t *result)
1237
0
{
1238
0
    if (py_get_monotonic_clock(result, NULL, 0) < 0) {
1239
0
        *result = 0;
1240
0
        return -1;
1241
0
    }
1242
0
    return 0;
1243
0
}
1244
1245
1246
int
1247
_PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1248
0
{
1249
0
    return py_get_monotonic_clock(tp, info, 1);
1250
0
}
1251
1252
1253
int
1254
_PyTime_PerfCounterWithInfo(PyTime_t *t, _Py_clock_info_t *info)
1255
0
{
1256
0
    return _PyTime_MonotonicWithInfo(t, info);
1257
0
}
1258
1259
1260
int
1261
PyTime_PerfCounter(PyTime_t *result)
1262
0
{
1263
0
    return PyTime_Monotonic(result);
1264
0
}
1265
1266
1267
int
1268
PyTime_PerfCounterRaw(PyTime_t *result)
1269
0
{
1270
0
    return PyTime_MonotonicRaw(result);
1271
0
}
1272
1273
1274
int
1275
_PyTime_localtime(time_t t, struct tm *tm)
1276
32
{
1277
#ifdef MS_WINDOWS
1278
    int error;
1279
1280
    error = localtime_s(tm, &t);
1281
    if (error != 0) {
1282
        errno = error;
1283
        PyErr_SetFromErrno(PyExc_OSError);
1284
        return -1;
1285
    }
1286
    return 0;
1287
#else /* !MS_WINDOWS */
1288
1289
#if defined(_AIX) && (SIZEOF_TIME_T < 8)
1290
    /* bpo-34373: AIX does not return NULL if t is too small or too large */
1291
    if (t < -2145916800 /* 1902-01-01 */
1292
       || t > 2145916800 /* 2038-01-01 */) {
1293
        errno = EINVAL;
1294
        PyErr_SetString(PyExc_OverflowError,
1295
                        "localtime argument out of range");
1296
        return -1;
1297
    }
1298
#endif
1299
1300
32
    errno = 0;
1301
32
    if (localtime_r(&t, tm) == NULL) {
1302
0
        if (errno == 0) {
1303
0
            errno = EINVAL;
1304
0
        }
1305
0
        PyErr_SetFromErrno(PyExc_OSError);
1306
0
        return -1;
1307
0
    }
1308
32
    return 0;
1309
32
#endif /* MS_WINDOWS */
1310
32
}
1311
1312
1313
int
1314
_PyTime_gmtime(time_t t, struct tm *tm)
1315
0
{
1316
#ifdef MS_WINDOWS
1317
    int error;
1318
1319
    error = gmtime_s(tm, &t);
1320
    if (error != 0) {
1321
        errno = error;
1322
        PyErr_SetFromErrno(PyExc_OSError);
1323
        return -1;
1324
    }
1325
    return 0;
1326
#else /* !MS_WINDOWS */
1327
0
    if (gmtime_r(&t, tm) == NULL) {
1328
0
#ifdef EINVAL
1329
0
        if (errno == 0) {
1330
0
            errno = EINVAL;
1331
0
        }
1332
0
#endif
1333
0
        PyErr_SetFromErrno(PyExc_OSError);
1334
0
        return -1;
1335
0
    }
1336
0
    return 0;
1337
0
#endif /* MS_WINDOWS */
1338
0
}
1339
1340
1341
PyTime_t
1342
_PyDeadline_Init(PyTime_t timeout)
1343
0
{
1344
0
    PyTime_t now;
1345
    // silently ignore error: cannot report error to the caller
1346
0
    (void)PyTime_MonotonicRaw(&now);
1347
0
    return _PyTime_Add(now, timeout);
1348
0
}
1349
1350
1351
PyTime_t
1352
_PyDeadline_Get(PyTime_t deadline)
1353
0
{
1354
0
    PyTime_t now;
1355
    // silently ignore error: cannot report error to the caller
1356
0
    (void)PyTime_MonotonicRaw(&now);
1357
0
    return deadline - now;
1358
0
}