Coverage Report

Created: 2025-11-24 06:11

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