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