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 ) {
0 commit comments