Coverage Report

Created: 2022-07-08 09:39

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