@@ -1027,9 +1027,76 @@ _PyTime_TimeWithInfo(PyTime_t *t, _Py_clock_info_t *info)
1027
1027
}
1028
1028
1029
1029
1030
+ #ifdef MS_WINDOWS
1031
+ static int
1032
+ py_win_perf_counter_frequency (_PyTimeFraction * base , int raise_exc )
1033
+ {
1034
+ LARGE_INTEGER freq ;
1035
+ // Since Windows XP, the function cannot fail.
1036
+ (void )QueryPerformanceFrequency (& freq );
1037
+ LONGLONG frequency = freq .QuadPart ;
1038
+
1039
+ // Since Windows XP, frequency cannot be zero.
1040
+ assert (frequency >= 1 );
1041
+
1042
+ Py_BUILD_ASSERT (sizeof (PyTime_t ) == sizeof (frequency ));
1043
+ PyTime_t denom = (PyTime_t )frequency ;
1044
+
1045
+ // Known QueryPerformanceFrequency() values:
1046
+ //
1047
+ // * 10,000,000 (10 MHz): 100 ns resolution
1048
+ // * 3,579,545 Hz (3.6 MHz): 279 ns resolution
1049
+ if (_PyTimeFraction_Set (base , SEC_TO_NS , denom ) < 0 ) {
1050
+ if (raise_exc ) {
1051
+ PyErr_SetString (PyExc_RuntimeError ,
1052
+ "invalid QueryPerformanceFrequency" );
1053
+ }
1054
+ return -1 ;
1055
+ }
1056
+ return 0 ;
1057
+ }
1058
+
1059
+
1060
+ // N.B. If raise_exc=0, this may be called without the GIL.
1061
+ static int
1062
+ py_get_win_perf_counter (PyTime_t * tp , _Py_clock_info_t * info , int raise_exc )
1063
+ {
1064
+ assert (info == NULL || raise_exc );
1065
+
1066
+ static _PyTimeFraction base = {0 , 0 };
1067
+ if (base .denom == 0 ) {
1068
+ if (py_win_perf_counter_frequency (& base , raise_exc ) < 0 ) {
1069
+ return -1 ;
1070
+ }
1071
+ }
1072
+
1073
+ if (info ) {
1074
+ info -> implementation = "QueryPerformanceCounter()" ;
1075
+ info -> resolution = _PyTimeFraction_Resolution (& base );
1076
+ info -> monotonic = 1 ;
1077
+ info -> adjustable = 0 ;
1078
+ }
1079
+
1080
+ LARGE_INTEGER now ;
1081
+ QueryPerformanceCounter (& now );
1082
+ LONGLONG ticksll = now .QuadPart ;
1083
+
1084
+ /* Make sure that casting LONGLONG to PyTime_t cannot overflow,
1085
+ both types are signed */
1086
+ PyTime_t ticks ;
1087
+ static_assert (sizeof (ticksll ) <= sizeof (ticks ),
1088
+ "LONGLONG is larger than PyTime_t" );
1089
+ ticks = (PyTime_t )ticksll ;
1090
+
1091
+ * tp = _PyTimeFraction_Mul (ticks , & base );
1092
+ return 0 ;
1093
+ }
1094
+ #endif // MS_WINDOWS
1095
+
1096
+
1030
1097
#ifdef __APPLE__
1031
1098
static int
1032
- py_mach_timebase_info (_PyTimeFraction * base , int raise )
1099
+ py_mach_timebase_info (_PyTimeFraction * base , int raise_exc )
1033
1100
{
1034
1101
mach_timebase_info_data_t timebase ;
1035
1102
// According to the Technical Q&A QA1398, mach_timebase_info() cannot
@@ -1051,7 +1118,7 @@ py_mach_timebase_info(_PyTimeFraction *base, int raise)
1051
1118
// * (1000000000, 33333335) on PowerPC: ~30 ns
1052
1119
// * (1000000000, 25000000) on PowerPC: 40 ns
1053
1120
if (_PyTimeFraction_Set (base , numer , denom ) < 0 ) {
1054
- if (raise ) {
1121
+ if (raise_exc ) {
1055
1122
PyErr_SetString (PyExc_RuntimeError ,
1056
1123
"invalid mach_timebase_info" );
1057
1124
}
@@ -1069,42 +1136,9 @@ py_get_monotonic_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
1069
1136
assert (info == NULL || raise_exc );
1070
1137
1071
1138
#if defined(MS_WINDOWS )
1072
- ULONGLONG ticks = GetTickCount64 ();
1073
- static_assert (sizeof (ticks ) <= sizeof (PyTime_t ),
1074
- "ULONGLONG is larger than PyTime_t" );
1075
- PyTime_t t ;
1076
- if (ticks <= (ULONGLONG )PyTime_MAX ) {
1077
- t = (PyTime_t )ticks ;
1078
- }
1079
- else {
1080
- // GetTickCount64() maximum is larger than PyTime_t maximum:
1081
- // ULONGLONG is unsigned, whereas PyTime_t is signed.
1082
- t = PyTime_MAX ;
1083
- }
1084
-
1085
- int res = pytime_mul (& t , MS_TO_NS );
1086
- * tp = t ;
1087
-
1088
- if (raise_exc && res < 0 ) {
1089
- pytime_overflow ();
1139
+ if (py_get_win_perf_counter (tp , info , raise_exc ) < 0 ) {
1090
1140
return -1 ;
1091
1141
}
1092
-
1093
- if (info ) {
1094
- DWORD timeAdjustment , timeIncrement ;
1095
- BOOL isTimeAdjustmentDisabled , ok ;
1096
- info -> implementation = "GetTickCount64()" ;
1097
- info -> monotonic = 1 ;
1098
- ok = GetSystemTimeAdjustment (& timeAdjustment , & timeIncrement ,
1099
- & isTimeAdjustmentDisabled );
1100
- if (!ok ) {
1101
- PyErr_SetFromWindowsErr (0 );
1102
- return -1 ;
1103
- }
1104
- info -> resolution = timeIncrement * 1e-7 ;
1105
- info -> adjustable = 0 ;
1106
- }
1107
-
1108
1142
#elif defined(__APPLE__ )
1109
1143
static _PyTimeFraction base = {0 , 0 };
1110
1144
if (base .denom == 0 ) {
@@ -1190,8 +1224,7 @@ _PyTime_MonotonicUnchecked(void)
1190
1224
{
1191
1225
PyTime_t t ;
1192
1226
if (py_get_monotonic_clock (& t , NULL , 0 ) < 0 ) {
1193
- // If mach_timebase_info(), clock_gettime() or gethrtime() fails:
1194
- // silently ignore the failure and return 0.
1227
+ // Ignore silently the error and return 0.
1195
1228
t = 0 ;
1196
1229
}
1197
1230
return t ;
@@ -1216,122 +1249,24 @@ _PyTime_MonotonicWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1216
1249
}
1217
1250
1218
1251
1219
- #ifdef MS_WINDOWS
1220
- static int
1221
- py_win_perf_counter_frequency (_PyTimeFraction * base , int raise )
1222
- {
1223
- LONGLONG frequency ;
1224
-
1225
- LARGE_INTEGER freq ;
1226
- // Since Windows XP, the function cannot fail.
1227
- (void )QueryPerformanceFrequency (& freq );
1228
- frequency = freq .QuadPart ;
1229
-
1230
- // Since Windows XP, frequency cannot be zero.
1231
- assert (frequency >= 1 );
1232
-
1233
- Py_BUILD_ASSERT (sizeof (PyTime_t ) == sizeof (frequency ));
1234
- PyTime_t denom = (PyTime_t )frequency ;
1235
-
1236
- // Known QueryPerformanceFrequency() values:
1237
- //
1238
- // * 10,000,000 (10 MHz): 100 ns resolution
1239
- // * 3,579,545 Hz (3.6 MHz): 279 ns resolution
1240
- if (_PyTimeFraction_Set (base , SEC_TO_NS , denom ) < 0 ) {
1241
- if (raise ) {
1242
- PyErr_SetString (PyExc_RuntimeError ,
1243
- "invalid QueryPerformanceFrequency" );
1244
- }
1245
- return -1 ;
1246
- }
1247
- return 0 ;
1248
- }
1249
-
1250
-
1251
- // N.B. If raise_exc=0, this may be called without the GIL.
1252
- static int
1253
- py_get_win_perf_counter (PyTime_t * tp , _Py_clock_info_t * info , int raise_exc )
1254
- {
1255
- assert (info == NULL || raise_exc );
1256
-
1257
- static _PyTimeFraction base = {0 , 0 };
1258
- if (base .denom == 0 ) {
1259
- if (py_win_perf_counter_frequency (& base , raise_exc ) < 0 ) {
1260
- return -1 ;
1261
- }
1262
- }
1263
-
1264
- if (info ) {
1265
- info -> implementation = "QueryPerformanceCounter()" ;
1266
- info -> resolution = _PyTimeFraction_Resolution (& base );
1267
- info -> monotonic = 1 ;
1268
- info -> adjustable = 0 ;
1269
- }
1270
-
1271
- LARGE_INTEGER now ;
1272
- QueryPerformanceCounter (& now );
1273
- LONGLONG ticksll = now .QuadPart ;
1274
-
1275
- /* Make sure that casting LONGLONG to PyTime_t cannot overflow,
1276
- both types are signed */
1277
- PyTime_t ticks ;
1278
- static_assert (sizeof (ticksll ) <= sizeof (ticks ),
1279
- "LONGLONG is larger than PyTime_t" );
1280
- ticks = (PyTime_t )ticksll ;
1281
-
1282
- PyTime_t ns = _PyTimeFraction_Mul (ticks , & base );
1283
- * tp = ns ;
1284
- return 0 ;
1285
- }
1286
- #endif // MS_WINDOWS
1287
-
1288
-
1289
1252
int
1290
1253
_PyTime_PerfCounterWithInfo (PyTime_t * t , _Py_clock_info_t * info )
1291
1254
{
1292
- #ifdef MS_WINDOWS
1293
- return py_get_win_perf_counter (t , info , 1 );
1294
- #else
1295
1255
return _PyTime_MonotonicWithInfo (t , info );
1296
- #endif
1297
1256
}
1298
1257
1299
1258
1300
1259
PyTime_t
1301
1260
_PyTime_PerfCounterUnchecked (void )
1302
1261
{
1303
- PyTime_t t ;
1304
- int res ;
1305
- #ifdef MS_WINDOWS
1306
- res = py_get_win_perf_counter (& t , NULL , 0 );
1307
- #else
1308
- res = py_get_monotonic_clock (& t , NULL , 0 );
1309
- #endif
1310
- if (res < 0 ) {
1311
- // If py_win_perf_counter_frequency() or py_get_monotonic_clock()
1312
- // fails: silently ignore the failure and return 0.
1313
- t = 0 ;
1314
- }
1315
- return t ;
1262
+ return _PyTime_MonotonicUnchecked ();
1316
1263
}
1317
1264
1318
1265
1319
1266
int
1320
1267
PyTime_PerfCounter (PyTime_t * result )
1321
1268
{
1322
- int res ;
1323
- #ifdef MS_WINDOWS
1324
- res = py_get_win_perf_counter (result , NULL , 1 );
1325
- #else
1326
- res = py_get_monotonic_clock (result , NULL , 1 );
1327
- #endif
1328
- if (res < 0 ) {
1329
- // If py_win_perf_counter_frequency() or py_get_monotonic_clock()
1330
- // fails: silently ignore the failure and return 0.
1331
- * result = 0 ;
1332
- return -1 ;
1333
- }
1334
- return 0 ;
1269
+ return PyTime_Monotonic (result );
1335
1270
}
1336
1271
1337
1272
0 commit comments