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 | #define _PyTime_check_mul_overflow(a, b) \ |
17 | (assert(b > 0), \ |
18 | (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \ |
19 | || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a)) |
20 | |
21 | /* To millisecond (10^-3) */ |
22 | #define SEC_TO_MS 1000 |
23 | |
24 | /* To microseconds (10^-6) */ |
25 | #define MS_TO_US 1000 |
26 | #define SEC_TO_US (SEC_TO_MS * MS_TO_US) |
27 | |
28 | /* To nanoseconds (10^-9) */ |
29 | #define US_TO_NS 1000 |
30 | #define MS_TO_NS (MS_TO_US * US_TO_NS) |
31 | #define SEC_TO_NS (SEC_TO_MS * MS_TO_NS) |
32 | |
33 | /* Conversion from nanoseconds */ |
34 | #define NS_TO_MS (1000 * 1000) |
35 | #define NS_TO_US (1000) |
36 | |
37 | static void |
38 | error_time_t_overflow(void) |
39 | { |
40 | PyErr_SetString(PyExc_OverflowError, |
41 | "timestamp out of range for platform time_t" ); |
42 | } |
43 | |
44 | static void |
45 | _PyTime_overflow(void) |
46 | { |
47 | PyErr_SetString(PyExc_OverflowError, |
48 | "timestamp too large to convert to C _PyTime_t" ); |
49 | } |
50 | |
51 | |
52 | _PyTime_t |
53 | _PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div) |
54 | { |
55 | _PyTime_t intpart, remaining; |
56 | /* Compute (ticks * mul / div) in two parts to prevent integer overflow: |
57 | compute integer part, and then the remaining part. |
58 | |
59 | (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div |
60 | |
61 | The caller must ensure that "(div - 1) * mul" cannot overflow. */ |
62 | intpart = ticks / div; |
63 | ticks %= div; |
64 | remaining = ticks * mul; |
65 | remaining /= div; |
66 | return intpart * mul + remaining; |
67 | } |
68 | |
69 | |
70 | time_t |
71 | _PyLong_AsTime_t(PyObject *obj) |
72 | { |
73 | #if SIZEOF_TIME_T == SIZEOF_LONG_LONG |
74 | long long val; |
75 | val = PyLong_AsLongLong(obj); |
76 | #else |
77 | long val; |
78 | Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); |
79 | val = PyLong_AsLong(obj); |
80 | #endif |
81 | if (val == -1 && PyErr_Occurred()) { |
82 | if (PyErr_ExceptionMatches(PyExc_OverflowError)) { |
83 | error_time_t_overflow(); |
84 | } |
85 | return -1; |
86 | } |
87 | return (time_t)val; |
88 | } |
89 | |
90 | PyObject * |
91 | _PyLong_FromTime_t(time_t t) |
92 | { |
93 | #if SIZEOF_TIME_T == SIZEOF_LONG_LONG |
94 | return PyLong_FromLongLong((long long)t); |
95 | #else |
96 | Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); |
97 | return PyLong_FromLong((long)t); |
98 | #endif |
99 | } |
100 | |
101 | /* Round to nearest with ties going to nearest even integer |
102 | (_PyTime_ROUND_HALF_EVEN) */ |
103 | static double |
104 | _PyTime_RoundHalfEven(double x) |
105 | { |
106 | double rounded = round(x); |
107 | if (fabs(x-rounded) == 0.5) { |
108 | /* halfway case: round to even */ |
109 | rounded = 2.0*round(x/2.0); |
110 | } |
111 | return rounded; |
112 | } |
113 | |
114 | static double |
115 | _PyTime_Round(double x, _PyTime_round_t round) |
116 | { |
117 | /* volatile avoids optimization changing how numbers are rounded */ |
118 | volatile double d; |
119 | |
120 | d = x; |
121 | if (round == _PyTime_ROUND_HALF_EVEN) { |
122 | d = _PyTime_RoundHalfEven(d); |
123 | } |
124 | else if (round == _PyTime_ROUND_CEILING) { |
125 | d = ceil(d); |
126 | } |
127 | else if (round == _PyTime_ROUND_FLOOR) { |
128 | d = floor(d); |
129 | } |
130 | else { |
131 | assert(round == _PyTime_ROUND_UP); |
132 | d = (d >= 0.0) ? ceil(d) : floor(d); |
133 | } |
134 | return d; |
135 | } |
136 | |
137 | static int |
138 | _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator, |
139 | long idenominator, _PyTime_round_t round) |
140 | { |
141 | double denominator = (double)idenominator; |
142 | double intpart; |
143 | /* volatile avoids optimization changing how numbers are rounded */ |
144 | volatile double floatpart; |
145 | |
146 | floatpart = modf(d, &intpart); |
147 | |
148 | floatpart *= denominator; |
149 | floatpart = _PyTime_Round(floatpart, round); |
150 | if (floatpart >= denominator) { |
151 | floatpart -= denominator; |
152 | intpart += 1.0; |
153 | } |
154 | else if (floatpart < 0) { |
155 | floatpart += denominator; |
156 | intpart -= 1.0; |
157 | } |
158 | assert(0.0 <= floatpart && floatpart < denominator); |
159 | |
160 | if (!_Py_InIntegralTypeRange(time_t, intpart)) { |
161 | error_time_t_overflow(); |
162 | return -1; |
163 | } |
164 | *sec = (time_t)intpart; |
165 | *numerator = (long)floatpart; |
166 | assert(0 <= *numerator && *numerator < idenominator); |
167 | return 0; |
168 | } |
169 | |
170 | static int |
171 | _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, |
172 | long denominator, _PyTime_round_t round) |
173 | { |
174 | assert(denominator >= 1); |
175 | |
176 | if (PyFloat_Check(obj)) { |
177 | double d = PyFloat_AsDouble(obj); |
178 | if (Py_IS_NAN(d)) { |
179 | *numerator = 0; |
180 | PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)" ); |
181 | return -1; |
182 | } |
183 | return _PyTime_DoubleToDenominator(d, sec, numerator, |
184 | denominator, round); |
185 | } |
186 | else { |
187 | *sec = _PyLong_AsTime_t(obj); |
188 | *numerator = 0; |
189 | if (*sec == (time_t)-1 && PyErr_Occurred()) { |
190 | return -1; |
191 | } |
192 | return 0; |
193 | } |
194 | } |
195 | |
196 | int |
197 | _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) |
198 | { |
199 | if (PyFloat_Check(obj)) { |
200 | double intpart; |
201 | /* volatile avoids optimization changing how numbers are rounded */ |
202 | volatile double d; |
203 | |
204 | d = PyFloat_AsDouble(obj); |
205 | if (Py_IS_NAN(d)) { |
206 | PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)" ); |
207 | return -1; |
208 | } |
209 | |
210 | d = _PyTime_Round(d, round); |
211 | (void)modf(d, &intpart); |
212 | |
213 | if (!_Py_InIntegralTypeRange(time_t, intpart)) { |
214 | error_time_t_overflow(); |
215 | return -1; |
216 | } |
217 | *sec = (time_t)intpart; |
218 | return 0; |
219 | } |
220 | else { |
221 | *sec = _PyLong_AsTime_t(obj); |
222 | if (*sec == (time_t)-1 && PyErr_Occurred()) { |
223 | return -1; |
224 | } |
225 | return 0; |
226 | } |
227 | } |
228 | |
229 | int |
230 | _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec, |
231 | _PyTime_round_t round) |
232 | { |
233 | return _PyTime_ObjectToDenominator(obj, sec, nsec, SEC_TO_NS, round); |
234 | } |
235 | |
236 | int |
237 | _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec, |
238 | _PyTime_round_t round) |
239 | { |
240 | return _PyTime_ObjectToDenominator(obj, sec, usec, SEC_TO_US, round); |
241 | } |
242 | |
243 | _PyTime_t |
244 | _PyTime_FromSeconds(int seconds) |
245 | { |
246 | _PyTime_t t; |
247 | /* ensure that integer overflow cannot happen, int type should have 32 |
248 | bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 |
249 | bits). */ |
250 | Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); |
251 | Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); |
252 | |
253 | t = (_PyTime_t)seconds; |
254 | assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) |
255 | || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); |
256 | t *= SEC_TO_NS; |
257 | return t; |
258 | } |
259 | |
260 | _PyTime_t |
261 | _PyTime_FromNanoseconds(_PyTime_t ns) |
262 | { |
263 | /* _PyTime_t already uses nanosecond resolution, no conversion needed */ |
264 | return ns; |
265 | } |
266 | |
267 | int |
268 | _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) |
269 | { |
270 | long long nsec; |
271 | _PyTime_t t; |
272 | |
273 | if (!PyLong_Check(obj)) { |
274 | PyErr_Format(PyExc_TypeError, "expect int, got %s" , |
275 | Py_TYPE(obj)->tp_name); |
276 | return -1; |
277 | } |
278 | |
279 | Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t)); |
280 | nsec = PyLong_AsLongLong(obj); |
281 | if (nsec == -1 && PyErr_Occurred()) { |
282 | if (PyErr_ExceptionMatches(PyExc_OverflowError)) { |
283 | _PyTime_overflow(); |
284 | } |
285 | return -1; |
286 | } |
287 | |
288 | /* _PyTime_t already uses nanosecond resolution, no conversion needed */ |
289 | t = (_PyTime_t)nsec; |
290 | *tp = t; |
291 | return 0; |
292 | } |
293 | |
294 | #ifdef HAVE_CLOCK_GETTIME |
295 | static int |
296 | pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) |
297 | { |
298 | _PyTime_t t, nsec; |
299 | int res = 0; |
300 | |
301 | Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); |
302 | t = (_PyTime_t)ts->tv_sec; |
303 | |
304 | if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { |
305 | if (raise) { |
306 | _PyTime_overflow(); |
307 | res = -1; |
308 | } |
309 | t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; |
310 | } |
311 | else { |
312 | t = t * SEC_TO_NS; |
313 | } |
314 | |
315 | nsec = ts->tv_nsec; |
316 | /* The following test is written for positive only nsec */ |
317 | assert(nsec >= 0); |
318 | if (t > _PyTime_MAX - nsec) { |
319 | if (raise) { |
320 | _PyTime_overflow(); |
321 | res = -1; |
322 | } |
323 | t = _PyTime_MAX; |
324 | } |
325 | else { |
326 | t += nsec; |
327 | } |
328 | |
329 | *tp = t; |
330 | return res; |
331 | } |
332 | |
333 | int |
334 | _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) |
335 | { |
336 | return pytime_fromtimespec(tp, ts, 1); |
337 | } |
338 | #endif |
339 | |
340 | #if !defined(MS_WINDOWS) |
341 | static int |
342 | pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) |
343 | { |
344 | _PyTime_t t, usec; |
345 | int res = 0; |
346 | |
347 | Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); |
348 | t = (_PyTime_t)tv->tv_sec; |
349 | |
350 | if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { |
351 | if (raise) { |
352 | _PyTime_overflow(); |
353 | res = -1; |
354 | } |
355 | t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; |
356 | } |
357 | else { |
358 | t = t * SEC_TO_NS; |
359 | } |
360 | |
361 | usec = (_PyTime_t)tv->tv_usec * US_TO_NS; |
362 | /* The following test is written for positive only usec */ |
363 | assert(usec >= 0); |
364 | if (t > _PyTime_MAX - usec) { |
365 | if (raise) { |
366 | _PyTime_overflow(); |
367 | res = -1; |
368 | } |
369 | t = _PyTime_MAX; |
370 | } |
371 | else { |
372 | t += usec; |
373 | } |
374 | |
375 | *tp = t; |
376 | return res; |
377 | } |
378 | |
379 | int |
380 | _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv) |
381 | { |
382 | return pytime_fromtimeval(tp, tv, 1); |
383 | } |
384 | #endif |
385 | |
386 | static int |
387 | _PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round, |
388 | long unit_to_ns) |
389 | { |
390 | /* volatile avoids optimization changing how numbers are rounded */ |
391 | volatile double d; |
392 | |
393 | /* convert to a number of nanoseconds */ |
394 | d = value; |
395 | d *= (double)unit_to_ns; |
396 | d = _PyTime_Round(d, round); |
397 | |
398 | if (!_Py_InIntegralTypeRange(_PyTime_t, d)) { |
399 | _PyTime_overflow(); |
400 | return -1; |
401 | } |
402 | *t = (_PyTime_t)d; |
403 | return 0; |
404 | } |
405 | |
406 | static int |
407 | _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, |
408 | long unit_to_ns) |
409 | { |
410 | if (PyFloat_Check(obj)) { |
411 | double d; |
412 | d = PyFloat_AsDouble(obj); |
413 | if (Py_IS_NAN(d)) { |
414 | PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)" ); |
415 | return -1; |
416 | } |
417 | return _PyTime_FromDouble(t, d, round, unit_to_ns); |
418 | } |
419 | else { |
420 | long long sec; |
421 | Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); |
422 | |
423 | sec = PyLong_AsLongLong(obj); |
424 | if (sec == -1 && PyErr_Occurred()) { |
425 | if (PyErr_ExceptionMatches(PyExc_OverflowError)) { |
426 | _PyTime_overflow(); |
427 | } |
428 | return -1; |
429 | } |
430 | |
431 | if (_PyTime_check_mul_overflow(sec, unit_to_ns)) { |
432 | _PyTime_overflow(); |
433 | return -1; |
434 | } |
435 | *t = sec * unit_to_ns; |
436 | return 0; |
437 | } |
438 | } |
439 | |
440 | int |
441 | _PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) |
442 | { |
443 | return _PyTime_FromObject(t, obj, round, SEC_TO_NS); |
444 | } |
445 | |
446 | int |
447 | _PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) |
448 | { |
449 | return _PyTime_FromObject(t, obj, round, MS_TO_NS); |
450 | } |
451 | |
452 | double |
453 | _PyTime_AsSecondsDouble(_PyTime_t t) |
454 | { |
455 | /* volatile avoids optimization changing how numbers are rounded */ |
456 | volatile double d; |
457 | |
458 | if (t % SEC_TO_NS == 0) { |
459 | _PyTime_t secs; |
460 | /* Divide using integers to avoid rounding issues on the integer part. |
461 | 1e-9 cannot be stored exactly in IEEE 64-bit. */ |
462 | secs = t / SEC_TO_NS; |
463 | d = (double)secs; |
464 | } |
465 | else { |
466 | d = (double)t; |
467 | d /= 1e9; |
468 | } |
469 | return d; |
470 | } |
471 | |
472 | PyObject * |
473 | _PyTime_AsNanosecondsObject(_PyTime_t t) |
474 | { |
475 | Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); |
476 | return PyLong_FromLongLong((long long)t); |
477 | } |
478 | |
479 | static _PyTime_t |
480 | _PyTime_Divide(const _PyTime_t t, const _PyTime_t k, |
481 | const _PyTime_round_t round) |
482 | { |
483 | assert(k > 1); |
484 | if (round == _PyTime_ROUND_HALF_EVEN) { |
485 | _PyTime_t x, r, abs_r; |
486 | x = t / k; |
487 | r = t % k; |
488 | abs_r = Py_ABS(r); |
489 | if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) { |
490 | if (t >= 0) { |
491 | x++; |
492 | } |
493 | else { |
494 | x--; |
495 | } |
496 | } |
497 | return x; |
498 | } |
499 | else if (round == _PyTime_ROUND_CEILING) { |
500 | if (t >= 0) { |
501 | return (t + k - 1) / k; |
502 | } |
503 | else { |
504 | return t / k; |
505 | } |
506 | } |
507 | else if (round == _PyTime_ROUND_FLOOR){ |
508 | if (t >= 0) { |
509 | return t / k; |
510 | } |
511 | else { |
512 | return (t - (k - 1)) / k; |
513 | } |
514 | } |
515 | else { |
516 | assert(round == _PyTime_ROUND_UP); |
517 | if (t >= 0) { |
518 | return (t + k - 1) / k; |
519 | } |
520 | else { |
521 | return (t - (k - 1)) / k; |
522 | } |
523 | } |
524 | } |
525 | |
526 | _PyTime_t |
527 | _PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round) |
528 | { |
529 | return _PyTime_Divide(t, NS_TO_MS, round); |
530 | } |
531 | |
532 | _PyTime_t |
533 | _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round) |
534 | { |
535 | return _PyTime_Divide(t, NS_TO_US, round); |
536 | } |
537 | |
538 | static int |
539 | _PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us, |
540 | _PyTime_round_t round) |
541 | { |
542 | _PyTime_t secs, ns; |
543 | int usec; |
544 | int res = 0; |
545 | |
546 | secs = t / SEC_TO_NS; |
547 | ns = t % SEC_TO_NS; |
548 | |
549 | usec = (int)_PyTime_Divide(ns, US_TO_NS, round); |
550 | if (usec < 0) { |
551 | usec += SEC_TO_US; |
552 | if (secs != _PyTime_MIN) { |
553 | secs -= 1; |
554 | } |
555 | else { |
556 | res = -1; |
557 | } |
558 | } |
559 | else if (usec >= SEC_TO_US) { |
560 | usec -= SEC_TO_US; |
561 | if (secs != _PyTime_MAX) { |
562 | secs += 1; |
563 | } |
564 | else { |
565 | res = -1; |
566 | } |
567 | } |
568 | assert(0 <= usec && usec < SEC_TO_US); |
569 | |
570 | *p_secs = secs; |
571 | *p_us = usec; |
572 | |
573 | return res; |
574 | } |
575 | |
576 | static int |
577 | _PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv, |
578 | _PyTime_round_t round, int raise) |
579 | { |
580 | _PyTime_t secs, secs2; |
581 | int us; |
582 | int res; |
583 | |
584 | res = _PyTime_AsTimeval_impl(t, &secs, &us, round); |
585 | |
586 | #ifdef MS_WINDOWS |
587 | tv->tv_sec = (long)secs; |
588 | #else |
589 | tv->tv_sec = secs; |
590 | #endif |
591 | tv->tv_usec = us; |
592 | |
593 | secs2 = (_PyTime_t)tv->tv_sec; |
594 | if (res < 0 || secs2 != secs) { |
595 | if (raise) { |
596 | error_time_t_overflow(); |
597 | } |
598 | return -1; |
599 | } |
600 | return 0; |
601 | } |
602 | |
603 | int |
604 | _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) |
605 | { |
606 | return _PyTime_AsTimevalStruct_impl(t, tv, round, 1); |
607 | } |
608 | |
609 | int |
610 | _PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) |
611 | { |
612 | return _PyTime_AsTimevalStruct_impl(t, tv, round, 0); |
613 | } |
614 | |
615 | int |
616 | _PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us, |
617 | _PyTime_round_t round) |
618 | { |
619 | _PyTime_t secs; |
620 | int res; |
621 | |
622 | res = _PyTime_AsTimeval_impl(t, &secs, us, round); |
623 | |
624 | *p_secs = secs; |
625 | |
626 | if (res < 0 || (_PyTime_t)*p_secs != secs) { |
627 | error_time_t_overflow(); |
628 | return -1; |
629 | } |
630 | return 0; |
631 | } |
632 | |
633 | |
634 | #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) |
635 | int |
636 | _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts) |
637 | { |
638 | _PyTime_t secs, nsec; |
639 | |
640 | secs = t / SEC_TO_NS; |
641 | nsec = t % SEC_TO_NS; |
642 | if (nsec < 0) { |
643 | nsec += SEC_TO_NS; |
644 | secs -= 1; |
645 | } |
646 | ts->tv_sec = (time_t)secs; |
647 | assert(0 <= nsec && nsec < SEC_TO_NS); |
648 | ts->tv_nsec = nsec; |
649 | |
650 | if ((_PyTime_t)ts->tv_sec != secs) { |
651 | error_time_t_overflow(); |
652 | return -1; |
653 | } |
654 | return 0; |
655 | } |
656 | #endif |
657 | |
658 | static int |
659 | py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) |
660 | { |
661 | #ifdef MS_WINDOWS |
662 | FILETIME system_time; |
663 | ULARGE_INTEGER large; |
664 | |
665 | assert(info == NULL || raise); |
666 | |
667 | GetSystemTimeAsFileTime(&system_time); |
668 | large.u.LowPart = system_time.dwLowDateTime; |
669 | large.u.HighPart = system_time.dwHighDateTime; |
670 | /* 11,644,473,600,000,000,000: number of nanoseconds between |
671 | the 1st january 1601 and the 1st january 1970 (369 years + 89 leap |
672 | days). */ |
673 | *tp = large.QuadPart * 100 - 11644473600000000000; |
674 | if (info) { |
675 | DWORD timeAdjustment, timeIncrement; |
676 | BOOL isTimeAdjustmentDisabled, ok; |
677 | |
678 | info->implementation = "GetSystemTimeAsFileTime()" ; |
679 | info->monotonic = 0; |
680 | ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, |
681 | &isTimeAdjustmentDisabled); |
682 | if (!ok) { |
683 | PyErr_SetFromWindowsErr(0); |
684 | return -1; |
685 | } |
686 | info->resolution = timeIncrement * 1e-7; |
687 | info->adjustable = 1; |
688 | } |
689 | |
690 | #else /* MS_WINDOWS */ |
691 | int err; |
692 | #if defined(HAVE_CLOCK_GETTIME) |
693 | struct timespec ts; |
694 | #endif |
695 | |
696 | #if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__) |
697 | struct timeval tv; |
698 | #endif |
699 | |
700 | assert(info == NULL || raise); |
701 | |
702 | #ifdef HAVE_CLOCK_GETTIME |
703 | |
704 | #ifdef HAVE_CLOCK_GETTIME_RUNTIME |
705 | if (HAVE_CLOCK_GETTIME_RUNTIME) { |
706 | #endif |
707 | |
708 | err = clock_gettime(CLOCK_REALTIME, &ts); |
709 | if (err) { |
710 | if (raise) { |
711 | PyErr_SetFromErrno(PyExc_OSError); |
712 | } |
713 | return -1; |
714 | } |
715 | if (pytime_fromtimespec(tp, &ts, raise) < 0) { |
716 | return -1; |
717 | } |
718 | |
719 | if (info) { |
720 | struct timespec res; |
721 | info->implementation = "clock_gettime(CLOCK_REALTIME)" ; |
722 | info->monotonic = 0; |
723 | info->adjustable = 1; |
724 | if (clock_getres(CLOCK_REALTIME, &res) == 0) { |
725 | info->resolution = res.tv_sec + res.tv_nsec * 1e-9; |
726 | } |
727 | else { |
728 | info->resolution = 1e-9; |
729 | } |
730 | } |
731 | |
732 | #ifdef HAVE_CLOCK_GETTIME_RUNTIME |
733 | } else { |
734 | #endif |
735 | |
736 | #endif |
737 | |
738 | #if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME) |
739 | |
740 | /* test gettimeofday() */ |
741 | err = gettimeofday(&tv, (struct timezone *)NULL); |
742 | if (err) { |
743 | if (raise) { |
744 | PyErr_SetFromErrno(PyExc_OSError); |
745 | } |
746 | return -1; |
747 | } |
748 | if (pytime_fromtimeval(tp, &tv, raise) < 0) { |
749 | return -1; |
750 | } |
751 | |
752 | if (info) { |
753 | info->implementation = "gettimeofday()" ; |
754 | info->resolution = 1e-6; |
755 | info->monotonic = 0; |
756 | info->adjustable = 1; |
757 | } |
758 | |
759 | #if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME) |
760 | } /* end of availibity block */ |
761 | #endif |
762 | |
763 | #endif /* !HAVE_CLOCK_GETTIME */ |
764 | #endif /* !MS_WINDOWS */ |
765 | return 0; |
766 | } |
767 | |
768 | _PyTime_t |
769 | _PyTime_GetSystemClock(void) |
770 | { |
771 | _PyTime_t t; |
772 | if (py_get_system_clock(&t, NULL, 0) < 0) { |
773 | // If clock_gettime(CLOCK_REALTIME) or gettimeofday() fails: |
774 | // silently ignore the failure and return 0. |
775 | t = 0; |
776 | } |
777 | return t; |
778 | } |
779 | |
780 | int |
781 | _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) |
782 | { |
783 | return py_get_system_clock(t, info, 1); |
784 | } |
785 | |
786 | #if __APPLE__ |
787 | static int |
788 | py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) |
789 | { |
790 | static mach_timebase_info_data_t timebase; |
791 | /* According to the Technical Q&A QA1398, mach_timebase_info() cannot |
792 | fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ |
793 | (void)mach_timebase_info(&timebase); |
794 | |
795 | /* Sanity check: should never occur in practice */ |
796 | if (timebase.numer < 1 || timebase.denom < 1) { |
797 | if (raise) { |
798 | PyErr_SetString(PyExc_RuntimeError, |
799 | "invalid mach_timebase_info" ); |
800 | } |
801 | return -1; |
802 | } |
803 | |
804 | /* Check that timebase.numer and timebase.denom can be casted to |
805 | _PyTime_t. In practice, timebase uses uint32_t, so casting cannot |
806 | overflow. At the end, only make sure that the type is uint32_t |
807 | (_PyTime_t is 64-bit long). */ |
808 | Py_BUILD_ASSERT(sizeof(timebase.numer) < sizeof(_PyTime_t)); |
809 | Py_BUILD_ASSERT(sizeof(timebase.denom) < sizeof(_PyTime_t)); |
810 | |
811 | /* Make sure that (ticks * timebase.numer) cannot overflow in |
812 | _PyTime_MulDiv(), with ticks < timebase.denom. |
813 | |
814 | Known time bases: |
815 | |
816 | * always (1, 1) on Intel |
817 | * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC |
818 | |
819 | None of these time bases can overflow with 64-bit _PyTime_t, but |
820 | check for overflow, just in case. */ |
821 | if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { |
822 | if (raise) { |
823 | PyErr_SetString(PyExc_OverflowError, |
824 | "mach_timebase_info is too large" ); |
825 | } |
826 | return -1; |
827 | } |
828 | |
829 | *pnumer = (_PyTime_t)timebase.numer; |
830 | *pdenom = (_PyTime_t)timebase.denom; |
831 | return 0; |
832 | } |
833 | #endif |
834 | |
835 | |
836 | static int |
837 | py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) |
838 | { |
839 | #if defined(MS_WINDOWS) |
840 | ULONGLONG ticks; |
841 | _PyTime_t t; |
842 | |
843 | assert(info == NULL || raise); |
844 | |
845 | ticks = GetTickCount64(); |
846 | Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); |
847 | t = (_PyTime_t)ticks; |
848 | |
849 | if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { |
850 | if (raise) { |
851 | _PyTime_overflow(); |
852 | return -1; |
853 | } |
854 | // Truncate to _PyTime_MAX silently. |
855 | *tp = _PyTime_MAX; |
856 | } |
857 | else { |
858 | *tp = t * MS_TO_NS; |
859 | } |
860 | |
861 | if (info) { |
862 | DWORD timeAdjustment, timeIncrement; |
863 | BOOL isTimeAdjustmentDisabled, ok; |
864 | info->implementation = "GetTickCount64()" ; |
865 | info->monotonic = 1; |
866 | ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, |
867 | &isTimeAdjustmentDisabled); |
868 | if (!ok) { |
869 | PyErr_SetFromWindowsErr(0); |
870 | return -1; |
871 | } |
872 | info->resolution = timeIncrement * 1e-7; |
873 | info->adjustable = 0; |
874 | } |
875 | |
876 | #elif defined(__APPLE__) |
877 | static _PyTime_t timebase_numer = 0; |
878 | static _PyTime_t timebase_denom = 0; |
879 | if (timebase_denom == 0) { |
880 | if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise) < 0) { |
881 | return -1; |
882 | } |
883 | } |
884 | |
885 | if (info) { |
886 | info->implementation = "mach_absolute_time()" ; |
887 | info->resolution = (double)timebase_numer / (double)timebase_denom * 1e-9; |
888 | info->monotonic = 1; |
889 | info->adjustable = 0; |
890 | } |
891 | |
892 | uint64_t ticks = mach_absolute_time(); |
893 | *tp = _PyTime_MulDiv((_PyTime_t)ticks, timebase_numer, timebase_denom); |
894 | |
895 | #elif defined(__hpux) |
896 | hrtime_t time; |
897 | |
898 | time = gethrtime(); |
899 | if (time == -1) { |
900 | if (raise) { |
901 | PyErr_SetFromErrno(PyExc_OSError); |
902 | } |
903 | return -1; |
904 | } |
905 | |
906 | *tp = time; |
907 | |
908 | if (info) { |
909 | info->implementation = "gethrtime()" ; |
910 | info->resolution = 1e-9; |
911 | info->monotonic = 1; |
912 | info->adjustable = 0; |
913 | } |
914 | |
915 | #else |
916 | struct timespec ts; |
917 | #ifdef CLOCK_HIGHRES |
918 | const clockid_t clk_id = CLOCK_HIGHRES; |
919 | const char *implementation = "clock_gettime(CLOCK_HIGHRES)" ; |
920 | #else |
921 | const clockid_t clk_id = CLOCK_MONOTONIC; |
922 | const char *implementation = "clock_gettime(CLOCK_MONOTONIC)" ; |
923 | #endif |
924 | |
925 | assert(info == NULL || raise); |
926 | |
927 | if (clock_gettime(clk_id, &ts) != 0) { |
928 | if (raise) { |
929 | PyErr_SetFromErrno(PyExc_OSError); |
930 | return -1; |
931 | } |
932 | return -1; |
933 | } |
934 | |
935 | if (info) { |
936 | struct timespec res; |
937 | info->monotonic = 1; |
938 | info->implementation = implementation; |
939 | info->adjustable = 0; |
940 | if (clock_getres(clk_id, &res) != 0) { |
941 | PyErr_SetFromErrno(PyExc_OSError); |
942 | return -1; |
943 | } |
944 | info->resolution = res.tv_sec + res.tv_nsec * 1e-9; |
945 | } |
946 | if (pytime_fromtimespec(tp, &ts, raise) < 0) { |
947 | return -1; |
948 | } |
949 | #endif |
950 | return 0; |
951 | } |
952 | |
953 | _PyTime_t |
954 | _PyTime_GetMonotonicClock(void) |
955 | { |
956 | _PyTime_t t; |
957 | if (py_get_monotonic_clock(&t, NULL, 0) < 0) { |
958 | // If mach_timebase_info(), clock_gettime() or gethrtime() fails: |
959 | // silently ignore the failure and return 0. |
960 | t = 0; |
961 | } |
962 | return t; |
963 | } |
964 | |
965 | int |
966 | _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) |
967 | { |
968 | return py_get_monotonic_clock(tp, info, 1); |
969 | } |
970 | |
971 | |
972 | #ifdef MS_WINDOWS |
973 | static int |
974 | win_perf_counter_frequency(LONGLONG *pfrequency, int raise) |
975 | { |
976 | LONGLONG frequency; |
977 | |
978 | LARGE_INTEGER freq; |
979 | if (!QueryPerformanceFrequency(&freq)) { |
980 | if (raise) { |
981 | PyErr_SetFromWindowsErr(0); |
982 | } |
983 | return -1; |
984 | } |
985 | frequency = freq.QuadPart; |
986 | |
987 | /* Sanity check: should never occur in practice */ |
988 | if (frequency < 1) { |
989 | if (raise) { |
990 | PyErr_SetString(PyExc_RuntimeError, |
991 | "invalid QueryPerformanceFrequency" ); |
992 | } |
993 | return -1; |
994 | } |
995 | |
996 | /* Check that frequency can be casted to _PyTime_t. |
997 | |
998 | Make also sure that (ticks * SEC_TO_NS) cannot overflow in |
999 | _PyTime_MulDiv(), with ticks < frequency. |
1000 | |
1001 | Known QueryPerformanceFrequency() values: |
1002 | |
1003 | * 10,000,000 (10 MHz): 100 ns resolution |
1004 | * 3,579,545 Hz (3.6 MHz): 279 ns resolution |
1005 | |
1006 | None of these frequencies can overflow with 64-bit _PyTime_t, but |
1007 | check for overflow, just in case. */ |
1008 | if (frequency > _PyTime_MAX |
1009 | || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) |
1010 | { |
1011 | if (raise) { |
1012 | PyErr_SetString(PyExc_OverflowError, |
1013 | "QueryPerformanceFrequency is too large" ); |
1014 | } |
1015 | return -1; |
1016 | } |
1017 | |
1018 | *pfrequency = frequency; |
1019 | return 0; |
1020 | } |
1021 | |
1022 | |
1023 | static int |
1024 | py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise) |
1025 | { |
1026 | static LONGLONG frequency = 0; |
1027 | if (frequency == 0) { |
1028 | if (win_perf_counter_frequency(&frequency, raise) < 0) { |
1029 | return -1; |
1030 | } |
1031 | } |
1032 | |
1033 | if (info) { |
1034 | info->implementation = "QueryPerformanceCounter()" ; |
1035 | info->resolution = 1.0 / (double)frequency; |
1036 | info->monotonic = 1; |
1037 | info->adjustable = 0; |
1038 | } |
1039 | |
1040 | LARGE_INTEGER now; |
1041 | QueryPerformanceCounter(&now); |
1042 | LONGLONG ticksll = now.QuadPart; |
1043 | |
1044 | /* Make sure that casting LONGLONG to _PyTime_t cannot overflow, |
1045 | both types are signed */ |
1046 | _PyTime_t ticks; |
1047 | Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks)); |
1048 | ticks = (_PyTime_t)ticksll; |
1049 | |
1050 | *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency); |
1051 | return 0; |
1052 | } |
1053 | #endif |
1054 | |
1055 | |
1056 | int |
1057 | _PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info) |
1058 | { |
1059 | #ifdef MS_WINDOWS |
1060 | return py_get_win_perf_counter(t, info, 1); |
1061 | #else |
1062 | return _PyTime_GetMonotonicClockWithInfo(t, info); |
1063 | #endif |
1064 | } |
1065 | |
1066 | |
1067 | _PyTime_t |
1068 | _PyTime_GetPerfCounter(void) |
1069 | { |
1070 | _PyTime_t t; |
1071 | int res; |
1072 | #ifdef MS_WINDOWS |
1073 | res = py_get_win_perf_counter(&t, NULL, 0); |
1074 | #else |
1075 | res = py_get_monotonic_clock(&t, NULL, 0); |
1076 | #endif |
1077 | if (res < 0) { |
1078 | // If win_perf_counter_frequency() or py_get_monotonic_clock() fails: |
1079 | // silently ignore the failure and return 0. |
1080 | t = 0; |
1081 | } |
1082 | return t; |
1083 | } |
1084 | |
1085 | |
1086 | int |
1087 | _PyTime_localtime(time_t t, struct tm *tm) |
1088 | { |
1089 | #ifdef MS_WINDOWS |
1090 | int error; |
1091 | |
1092 | error = localtime_s(tm, &t); |
1093 | if (error != 0) { |
1094 | errno = error; |
1095 | PyErr_SetFromErrno(PyExc_OSError); |
1096 | return -1; |
1097 | } |
1098 | return 0; |
1099 | #else /* !MS_WINDOWS */ |
1100 | |
1101 | #if defined(_AIX) && (SIZEOF_TIME_T < 8) |
1102 | /* bpo-34373: AIX does not return NULL if t is too small or too large */ |
1103 | if (t < -2145916800 /* 1902-01-01 */ |
1104 | || t > 2145916800 /* 2038-01-01 */) { |
1105 | errno = EINVAL; |
1106 | PyErr_SetString(PyExc_OverflowError, |
1107 | "localtime argument out of range" ); |
1108 | return -1; |
1109 | } |
1110 | #endif |
1111 | |
1112 | errno = 0; |
1113 | if (localtime_r(&t, tm) == NULL) { |
1114 | if (errno == 0) { |
1115 | errno = EINVAL; |
1116 | } |
1117 | PyErr_SetFromErrno(PyExc_OSError); |
1118 | return -1; |
1119 | } |
1120 | return 0; |
1121 | #endif /* MS_WINDOWS */ |
1122 | } |
1123 | |
1124 | int |
1125 | _PyTime_gmtime(time_t t, struct tm *tm) |
1126 | { |
1127 | #ifdef MS_WINDOWS |
1128 | int error; |
1129 | |
1130 | error = gmtime_s(tm, &t); |
1131 | if (error != 0) { |
1132 | errno = error; |
1133 | PyErr_SetFromErrno(PyExc_OSError); |
1134 | return -1; |
1135 | } |
1136 | return 0; |
1137 | #else /* !MS_WINDOWS */ |
1138 | if (gmtime_r(&t, tm) == NULL) { |
1139 | #ifdef EINVAL |
1140 | if (errno == 0) { |
1141 | errno = EINVAL; |
1142 | } |
1143 | #endif |
1144 | PyErr_SetFromErrno(PyExc_OSError); |
1145 | return -1; |
1146 | } |
1147 | return 0; |
1148 | #endif /* MS_WINDOWS */ |
1149 | } |
1150 | |