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