• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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