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
error_time_t_overflow(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
_PyTime_overflow(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
_PyTime_MulDiv(_PyTime_t ticks,_PyTime_t mul,_PyTime_t div)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
_PyLong_AsTime_t(PyObject * obj)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 *
_PyLong_FromTime_t(time_t t)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
_PyTime_RoundHalfEven(double x)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
_PyTime_Round(double x,_PyTime_round_t round)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
_PyTime_DoubleToDenominator(double d,time_t * sec,long * numerator,long idenominator,_PyTime_round_t round)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
_PyTime_ObjectToDenominator(PyObject * obj,time_t * sec,long * numerator,long denominator,_PyTime_round_t round)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
_PyTime_ObjectToTime_t(PyObject * obj,time_t * sec,_PyTime_round_t round)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
_PyTime_ObjectToTimespec(PyObject * obj,time_t * sec,long * nsec,_PyTime_round_t round)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
_PyTime_ObjectToTimeval(PyObject * obj,time_t * sec,long * usec,_PyTime_round_t round)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
_PyTime_FromSeconds(int seconds)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
_PyTime_FromNanoseconds(_PyTime_t ns)261 _PyTime_FromNanoseconds(_PyTime_t ns)
262 {
263 /* _PyTime_t already uses nanosecond resolution, no conversion needed */
264 return ns;
265 }
266
267 int
_PyTime_FromNanosecondsObject(_PyTime_t * tp,PyObject * obj)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
pytime_fromtimespec(_PyTime_t * tp,struct timespec * ts,int raise)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
_PyTime_FromTimespec(_PyTime_t * tp,struct timespec * ts)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
pytime_fromtimeval(_PyTime_t * tp,struct timeval * tv,int raise)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
_PyTime_FromTimeval(_PyTime_t * tp,struct timeval * tv)380 _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
381 {
382 return pytime_fromtimeval(tp, tv, 1);
383 }
384 #endif
385
386 static int
_PyTime_FromDouble(_PyTime_t * t,double value,_PyTime_round_t round,long unit_to_ns)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
_PyTime_FromObject(_PyTime_t * t,PyObject * obj,_PyTime_round_t round,long unit_to_ns)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
_PyTime_FromSecondsObject(_PyTime_t * t,PyObject * obj,_PyTime_round_t round)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
_PyTime_FromMillisecondsObject(_PyTime_t * t,PyObject * obj,_PyTime_round_t round)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
_PyTime_AsSecondsDouble(_PyTime_t t)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 *
_PyTime_AsNanosecondsObject(_PyTime_t t)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
_PyTime_Divide(const _PyTime_t t,const _PyTime_t k,const _PyTime_round_t round)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
_PyTime_AsMilliseconds(_PyTime_t t,_PyTime_round_t round)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
_PyTime_AsMicroseconds(_PyTime_t t,_PyTime_round_t round)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
_PyTime_AsTimeval_impl(_PyTime_t t,_PyTime_t * p_secs,int * p_us,_PyTime_round_t round)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
_PyTime_AsTimevalStruct_impl(_PyTime_t t,struct timeval * tv,_PyTime_round_t round,int raise)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
_PyTime_AsTimeval(_PyTime_t t,struct timeval * tv,_PyTime_round_t round)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
_PyTime_AsTimeval_noraise(_PyTime_t t,struct timeval * tv,_PyTime_round_t round)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
_PyTime_AsTimevalTime_t(_PyTime_t t,time_t * p_secs,int * us,_PyTime_round_t round)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
_PyTime_AsTimespec(_PyTime_t t,struct timespec * ts)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
py_get_system_clock(_PyTime_t * tp,_Py_clock_info_t * info,int raise)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
_PyTime_GetSystemClock(void)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
_PyTime_GetSystemClockWithInfo(_PyTime_t * t,_Py_clock_info_t * info)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
py_mach_timebase_info(_PyTime_t * pnumer,_PyTime_t * pdenom,int raise)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
py_get_monotonic_clock(_PyTime_t * tp,_Py_clock_info_t * info,int raise)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
_PyTime_GetMonotonicClock(void)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
_PyTime_GetMonotonicClockWithInfo(_PyTime_t * tp,_Py_clock_info_t * info)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
win_perf_counter_frequency(LONGLONG * pfrequency,int raise)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
py_get_win_perf_counter(_PyTime_t * tp,_Py_clock_info_t * info,int raise)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
_PyTime_GetPerfCounterWithInfo(_PyTime_t * t,_Py_clock_info_t * info)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
_PyTime_GetPerfCounter(void)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
_PyTime_localtime(time_t t,struct tm * tm)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
_PyTime_gmtime(time_t t,struct tm * tm)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