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