| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 09796f2 commit d62d925
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -125,9 +125,11 @@ PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t, | |||
| 125 | 125 | object. */ | |
| 126 | 126 | PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); | |
| 127 | 127 | ||
| 128 | + #ifndef MS_WINDOWS | ||
| 128 | 129 | /* Create a timestamp from a timeval structure. | |
| 129 | 130 | Raise an exception and return -1 on overflow, return 0 on success. */ | |
| 130 | 131 | PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); | |
| 132 | + #endif | ||
| 131 | 133 | ||
| 132 | 134 | /* Convert a timestamp to a timeval structure (microsecond resolution). | |
| 133 | 135 | tv_usec is always positive. | |
@@ -188,7 +190,7 @@ typedef struct { | |||
| 188 | 190 | ||
| 189 | 191 | If the internal clock fails, silently ignore the error and return 0. | |
| 190 | 192 | On integer overflow, silently ignore the overflow and clamp the clock to | |
| 191 | - _PyTime_MIN or _PyTime_MAX. | ||
| 193 | + [_PyTime_MIN; _PyTime_MAX]. | ||
| 192 | 194 | ||
| 193 | 195 | Use _PyTime_GetSystemClockWithInfo() to check for failure. */ | |
| 194 | 196 | PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); | |
@@ -208,7 +210,7 @@ PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( | |||
| 208 | 210 | ||
| 209 | 211 | If the internal clock fails, silently ignore the error and return 0. | |
| 210 | 212 | On integer overflow, silently ignore the overflow and clamp the clock to | |
| 211 | - _PyTime_MIN or _PyTime_MAX. | ||
| 213 | + [_PyTime_MIN; _PyTime_MAX]. | ||
| 212 | 214 | ||
| 213 | 215 | Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */ | |
| 214 | 216 | PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); | |
@@ -239,7 +241,7 @@ PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); | |||
| 239 | 241 | ||
| 240 | 242 | If the internal clock fails, silently ignore the error and return 0. | |
| 241 | 243 | On integer overflow, silently ignore the overflow and clamp the clock to | |
| 242 | - _PyTime_MIN or _PyTime_MAX. | ||
| 244 | + [_PyTime_MIN; _PyTime_MAX]. | ||
| 243 | 245 | ||
| 244 | 246 | Use _PyTime_GetPerfCounterWithInfo() to check for failure. */ | |
| 245 | 247 | PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,11 +13,6 @@ | |||
| 13 | 13 | #endif | |
| 14 | 14 | #endif | |
| 15 | 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 | 16 | /* To millisecond (10^-3) */ | |
| 22 | 17 | #define SEC_TO_MS 1000 | |
| 23 | 18 | ||
@@ -78,6 +73,49 @@ pytime_as_nanoseconds(_PyTime_t t) | |||
| 78 | 73 | } | |
| 79 | 74 | ||
| 80 | 75 | ||
| 76 | + // Compute t + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. | ||
| 77 | + static inline _PyTime_t | ||
| 78 | + pytime_add(_PyTime_t *t, _PyTime_t t2) | ||
| 79 | + { | ||
| 80 | + if (t2 > 0 && *t > _PyTime_MAX - t2) { | ||
| 81 | + *t = _PyTime_MAX; | ||
| 82 | + return -1; | ||
| 83 | + } | ||
| 84 | + else if (t2 < 0 && *t < _PyTime_MIN - t2) { | ||
| 85 | + *t = _PyTime_MIN; | ||
| 86 | + return -1; | ||
| 87 | + } | ||
| 88 | + else { | ||
| 89 | + *t += t2; | ||
| 90 | + return 0; | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + static inline int | ||
| 96 | + _PyTime_check_mul_overflow(_PyTime_t a, _PyTime_t b) | ||
| 97 | + { | ||
| 98 | + assert(b > 0); | ||
| 99 | + return ((a < _PyTime_MIN / b) || (_PyTime_MAX / b < a)); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + | ||
| 103 | + // Compute t * k. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. | ||
| 104 | + static inline _PyTime_t | ||
| 105 | + pytime_mul(_PyTime_t *t, _PyTime_t k) | ||
| 106 | + { | ||
| 107 | + assert(k > 0); | ||
| 108 | + if (_PyTime_check_mul_overflow(*t, k)) { | ||
| 109 | + *t = (*t >= 0) ? _PyTime_MAX : _PyTime_MIN; | ||
| 110 | + return -1; | ||
| 111 | + } | ||
| 112 | + else { | ||
| 113 | + *t *= k; | ||
| 114 | + return 0; | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + | ||
| 81 | 119 | _PyTime_t | |
| 82 | 120 | _PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div) | |
| 83 | 121 | { | |
@@ -371,41 +409,25 @@ _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) | |||
| 371 | 409 | ||
| 372 | 410 | #ifdef HAVE_CLOCK_GETTIME | |
| 373 | 411 | static int | |
| 374 | - pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) | ||
| 412 | + pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise_exc) | ||
| 375 | 413 | { | |
| 376 | 414 | _PyTime_t t, tv_nsec; | |
| 377 | - int res = 0; | ||
| 378 | 415 | ||
| 379 | 416 | Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); | |
| 380 | 417 | t = (_PyTime_t)ts->tv_sec; | |
| 381 | 418 | ||
| 382 | - if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { | ||
| 383 | - if (raise) { | ||
| 384 | - pytime_overflow(); | ||
| 385 | - res = -1; | ||
| 386 | - } | ||
| 387 | - t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; | ||
| 388 | - } | ||
| 389 | - else { | ||
| 390 | - t = t * SEC_TO_NS; | ||
| 391 | - } | ||
| 419 | + int res1 = pytime_mul(&t, SEC_TO_NS); | ||
| 392 | 420 | ||
| 393 | 421 | tv_nsec = ts->tv_nsec; | |
| 394 | - /* The following test is written for positive only tv_nsec */ | ||
| 395 | - assert(tv_nsec >= 0); | ||
| 396 | - if (t > _PyTime_MAX - tv_nsec) { | ||
| 397 | - if (raise) { | ||
| 398 | - pytime_overflow(); | ||
| 399 | - res = -1; | ||
| 400 | - } | ||
| 401 | - t = _PyTime_MAX; | ||
| 402 | - } | ||
| 403 | - else { | ||
| 404 | - t += tv_nsec; | ||
| 405 | - } | ||
| 422 | + int res2 = pytime_add(&t, tv_nsec); | ||
| 406 | 423 | ||
| 407 | 424 | *tp = pytime_from_nanoseconds(t); | |
| 408 | - return res; | ||
| 425 | + | ||
| 426 | + if (raise_exc && (res1 < 0 || res2 < 0)) { | ||
| 427 | + pytime_overflow(); | ||
| 428 | + return -1; | ||
| 429 | + } | ||
| 430 | + return 0; | ||
| 409 | 431 | } | |
| 410 | 432 | ||
| 411 | 433 | int | |
@@ -416,43 +438,25 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) | |||
| 416 | 438 | #endif | |
| 417 | 439 | ||
| 418 | 440 | ||
| 419 | - #if !defined(MS_WINDOWS) | ||
| 441 | + #ifndef MS_WINDOWS | ||
| 420 | 442 | static int | |
| 421 | - pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) | ||
| 443 | + pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise_exc) | ||
| 422 | 444 | { | |
| 423 | - _PyTime_t t, usec; | ||
| 424 | - int res = 0; | ||
| 425 | - | ||
| 426 | 445 | Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); | |
| 427 | - t = (_PyTime_t)tv->tv_sec; | ||
| 446 | + _PyTime_t t = (_PyTime_t)tv->tv_sec; | ||
| 428 | 447 | ||
| 429 | - if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { | ||
| 430 | - if (raise) { | ||
| 431 | - pytime_overflow(); | ||
| 432 | - res = -1; | ||
| 433 | - } | ||
| 434 | - t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; | ||
| 435 | - } | ||
| 436 | - else { | ||
| 437 | - t = t * SEC_TO_NS; | ||
| 438 | - } | ||
| 448 | + int res1 = pytime_mul(&t, SEC_TO_NS); | ||
| 439 | 449 | ||
| 440 | - usec = (_PyTime_t)tv->tv_usec * US_TO_NS; | ||
| 441 | - /* The following test is written for positive only usec */ | ||
| 442 | - assert(usec >= 0); | ||
| 443 | - if (t > _PyTime_MAX - usec) { | ||
| 444 | - if (raise) { | ||
| 445 | - pytime_overflow(); | ||
| 446 | - res = -1; | ||
| 447 | - } | ||
| 448 | - t = _PyTime_MAX; | ||
| 449 | - } | ||
| 450 | - else { | ||
| 451 | - t += usec; | ||
| 452 | - } | ||
| 450 | + _PyTime_t usec = (_PyTime_t)tv->tv_usec * US_TO_NS; | ||
| 451 | + int res2 = pytime_add(&t, usec); | ||
| 453 | 452 | ||
| 454 | 453 | *tp = pytime_from_nanoseconds(t); | |
| 455 | - return res; | ||
| 454 | + | ||
| 455 | + if (raise_exc && (res1 < 0 || res2 < 0)) { | ||
| 456 | + pytime_overflow(); | ||
| 457 | + return -1; | ||
| 458 | + } | ||
| 459 | + return 0; | ||
| 456 | 460 | } | |
| 457 | 461 | ||
| 458 | 462 | ||
@@ -572,7 +576,7 @@ pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k) | |||
| 572 | 576 | assert(k > 1); | |
| 573 | 577 | if (t >= 0) { | |
| 574 | 578 | // Don't use (t + k - 1) / k to avoid integer overflow | |
| 575 | - // if t=_PyTime_MAX | ||
| 579 | + // if t is equal to _PyTime_MAX | ||
| 576 | 580 | _PyTime_t q = t / k; | |
| 577 | 581 | if (t % k) { | |
| 578 | 582 | q += 1; | |
@@ -581,7 +585,7 @@ pytime_divide_round_up(const _PyTime_t t, const _PyTime_t k) | |||
| 581 | 585 | } | |
| 582 | 586 | else { | |
| 583 | 587 | // Don't use (t - (k - 1)) / k to avoid integer overflow | |
| 584 | - // if t=_PyTime_MIN | ||
| 588 | + // if t is equals to _PyTime_MIN. | ||
| 585 | 589 | _PyTime_t q = t / k; | |
| 586 | 590 | if (t % k) { | |
| 587 | 591 | q -= 1; | |
@@ -804,14 +808,14 @@ _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts) | |||
| 804 | 808 | ||
| 805 | 809 | ||
| 806 | 810 | static int | |
| 807 | - py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | ||
| 811 | + py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) | ||
| 808 | 812 | { | |
| 813 | + assert(info == NULL || raise_exc); | ||
| 814 | + | ||
| 809 | 815 | #ifdef MS_WINDOWS | |
| 810 | 816 | FILETIME system_time; | |
| 811 | 817 | ULARGE_INTEGER large; | |
| 812 | 818 | ||
| 813 | - assert(info == NULL || raise); | ||
| 814 | - | ||
| 815 | 819 | GetSystemTimeAsFileTime(&system_time); | |
| 816 | 820 | large.u.LowPart = system_time.dwLowDateTime; | |
| 817 | 821 | large.u.HighPart = system_time.dwHighDateTime; | |
@@ -846,8 +850,6 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 846 | 850 | struct timeval tv; | |
| 847 | 851 | #endif | |
| 848 | 852 | ||
| 849 | - assert(info == NULL || raise); | ||
| 850 | - | ||
| 851 | 853 | #ifdef HAVE_CLOCK_GETTIME | |
| 852 | 854 | ||
| 853 | 855 | #ifdef HAVE_CLOCK_GETTIME_RUNTIME | |
@@ -856,12 +858,12 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 856 | 858 | ||
| 857 | 859 | err = clock_gettime(CLOCK_REALTIME, &ts); | |
| 858 | 860 | if (err) { | |
| 859 | - if (raise) { | ||
| 861 | + if (raise_exc) { | ||
| 860 | 862 | PyErr_SetFromErrno(PyExc_OSError); | |
| 861 | 863 | } | |
| 862 | 864 | return -1; | |
| 863 | 865 | } | |
| 864 | - if (pytime_fromtimespec(tp, &ts, raise) < 0) { | ||
| 866 | + if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) { | ||
| 865 | 867 | return -1; | |
| 866 | 868 | } | |
| 867 | 869 | ||
@@ -890,12 +892,12 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 890 | 892 | /* test gettimeofday() */ | |
| 891 | 893 | err = gettimeofday(&tv, (struct timezone *)NULL); | |
| 892 | 894 | if (err) { | |
| 893 | - if (raise) { | ||
| 895 | + if (raise_exc) { | ||
| 894 | 896 | PyErr_SetFromErrno(PyExc_OSError); | |
| 895 | 897 | } | |
| 896 | 898 | return -1; | |
| 897 | 899 | } | |
| 898 | - if (pytime_fromtimeval(tp, &tv, raise) < 0) { | ||
| 900 | + if (pytime_fromtimeval(tp, &tv, raise_exc) < 0) { | ||
| 899 | 901 | return -1; | |
| 900 | 902 | } | |
| 901 | 903 | ||
@@ -987,28 +989,21 @@ py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) | |||
| 987 | 989 | ||
| 988 | 990 | ||
| 989 | 991 | static int | |
| 990 | - py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | ||
| 992 | + py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) | ||
| 991 | 993 | { | |
| 992 | - #if defined(MS_WINDOWS) | ||
| 993 | - ULONGLONG ticks; | ||
| 994 | - _PyTime_t t; | ||
| 995 | - | ||
| 996 | - assert(info == NULL || raise); | ||
| 994 | + assert(info == NULL || raise_exc); | ||
| 997 | 995 | ||
| 998 | - ticks = GetTickCount64(); | ||
| 996 | + #if defined(MS_WINDOWS) | ||
| 997 | + ULONGLONG ticks = GetTickCount64(); | ||
| 999 | 998 | Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); | |
| 1000 | - t = (_PyTime_t)ticks; | ||
| 999 | + _PyTime_t t = (_PyTime_t)ticks; | ||
| 1001 | 1000 | ||
| 1002 | - if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { | ||
| 1003 | - if (raise) { | ||
| 1004 | - pytime_overflow(); | ||
| 1005 | - return -1; | ||
| 1006 | - } | ||
| 1007 | - // Clamp to _PyTime_MAX silently. | ||
| 1008 | - *tp = _PyTime_MAX; | ||
| 1009 | - } | ||
| 1010 | - else { | ||
| 1011 | - *tp = t * MS_TO_NS; | ||
| 1001 | + int res = pytime_mul(&t, MS_TO_NS); | ||
| 1002 | + *tp = t; | ||
| 1003 | + | ||
| 1004 | + if (raise_exc && res < 0) { | ||
| 1005 | + pytime_overflow(); | ||
| 1006 | + return -1; | ||
| 1012 | 1007 | } | |
| 1013 | 1008 | ||
| 1014 | 1009 | if (info) { | |
@@ -1030,7 +1025,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 1030 | 1025 | static _PyTime_t timebase_numer = 0; | |
| 1031 | 1026 | static _PyTime_t timebase_denom = 0; | |
| 1032 | 1027 | if (timebase_denom == 0) { | |
| 1033 | - if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise) < 0) { | ||
| 1028 | + if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise_exc) < 0) { | ||
| 1034 | 1029 | return -1; | |
| 1035 | 1030 | } | |
| 1036 | 1031 | } | |
@@ -1055,7 +1050,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 1055 | 1050 | ||
| 1056 | 1051 | time = gethrtime(); | |
| 1057 | 1052 | if (time == -1) { | |
| 1058 | - if (raise) { | ||
| 1053 | + if (raise_exc) { | ||
| 1059 | 1054 | PyErr_SetFromErrno(PyExc_OSError); | |
| 1060 | 1055 | } | |
| 1061 | 1056 | return -1; | |
@@ -1071,7 +1066,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 1071 | 1066 | } | |
| 1072 | 1067 | ||
| 1073 | 1068 | #else | |
| 1074 | - struct timespec ts; | ||
| 1069 | + | ||
| 1075 | 1070 | #ifdef CLOCK_HIGHRES | |
| 1076 | 1071 | const clockid_t clk_id = CLOCK_HIGHRES; | |
| 1077 | 1072 | const char *implementation = "clock_gettime(CLOCK_HIGHRES)"; | |
@@ -1080,30 +1075,30 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |||
| 1080 | 1075 | const char *implementation = "clock_gettime(CLOCK_MONOTONIC)"; | |
| 1081 | 1076 | #endif | |
| 1082 | 1077 | ||
| 1083 | - assert(info == NULL || raise); | ||
| 1084 | - | ||
| 1078 | + struct timespec ts; | ||
| 1085 | 1079 | if (clock_gettime(clk_id, &ts) != 0) { | |
| 1086 | - if (raise) { | ||
| 1080 | + if (raise_exc) { | ||
| 1087 | 1081 | PyErr_SetFromErrno(PyExc_OSError); | |
| 1088 | 1082 | return -1; | |
| 1089 | 1083 | } | |
| 1090 | 1084 | return -1; | |
| 1091 | 1085 | } | |
| 1092 | 1086 | ||
| 1087 | + if (pytime_fromtimespec(tp, &ts, raise_exc) < 0) { | ||
| 1088 | + return -1; | ||
| 1089 | + } | ||
| 1090 | + | ||
| 1093 | 1091 | if (info) { | |
| 1094 | - struct timespec res; | ||
| 1095 | 1092 | info->monotonic = 1; | |
| 1096 | 1093 | info->implementation = implementation; | |
| 1097 | 1094 | info->adjustable = 0; | |
| 1095 | + struct timespec res; | ||
| 1098 | 1096 | if (clock_getres(clk_id, &res) != 0) { | |
| 1099 | 1097 | PyErr_SetFromErrno(PyExc_OSError); | |
| 1100 | 1098 | return -1; | |
| 1101 | 1099 | } | |
| 1102 | 1100 | info->resolution = res.tv_sec + res.tv_nsec * 1e-9; | |
| 1103 | 1101 | } | |
| 1104 | - if (pytime_fromtimespec(tp, &ts, raise) < 0) { | ||
| 1105 | - return -1; | ||
| 1106 | - } | ||
| 1107 | 1102 | #endif | |
| 1108 | 1103 | return 0; | |
| 1109 | 1104 | } | |
@@ -1169,6 +1164,8 @@ py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise) | |||
| 1169 | 1164 | static int | |
| 1170 | 1165 | py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise) | |
| 1171 | 1166 | { | |
| 1167 | + assert(info == NULL || raise_exc); | ||
| 1168 | + | ||
| 1172 | 1169 | static LONGLONG frequency = 0; | |
| 1173 | 1170 | if (frequency == 0) { | |
| 1174 | 1171 | if (py_win_perf_counter_frequency(&frequency, raise) < 0) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments