|
62 | 62 | #define SEC_TO_NS (1000 * 1000 * 1000)
|
63 | 63 |
|
64 | 64 |
|
| 65 | +#ifdef HAVE_TIMES |
| 66 | + |
| 67 | +static int |
| 68 | +check_ticks_per_second(long tps, const char *context) |
| 69 | +{ |
| 70 | + /* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) |
| 71 | + cannot overflow. */ |
| 72 | + if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) { |
| 73 | + PyErr_Format(PyExc_OverflowError, "%s is too large", context); |
| 74 | + return -1; |
| 75 | + } |
| 76 | + return 0; |
| 77 | +} |
| 78 | + |
| 79 | +# define ticks_per_second _PyRuntime.time.ticks_per_second |
| 80 | + |
| 81 | +static void |
| 82 | +ensure_ticks_per_second(void) |
| 83 | +{ |
| 84 | + if (_PyRuntime.time.ticks_per_second_initialized) { |
| 85 | + return; |
| 86 | + } |
| 87 | + _PyRuntime.time.ticks_per_second_initialized = 1; |
| 88 | +# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) |
| 89 | + ticks_per_second = sysconf(_SC_CLK_TCK); |
| 90 | + if (ticks_per_second < 1) { |
| 91 | + ticks_per_second = -1; |
| 92 | + } |
| 93 | +# elif defined(HZ) |
| 94 | + ticks_per_second = HZ; |
| 95 | +# else |
| 96 | + ticks_per_second = 60; /* magic fallback value; may be bogus */ |
| 97 | +# endif |
| 98 | +} |
| 99 | + |
| 100 | +#endif /* HAVE_TIMES */ |
| 101 | + |
| 102 | + |
| 103 | +PyStatus |
| 104 | +_PyTime_Init(void) |
| 105 | +{ |
| 106 | +#ifdef HAVE_TIMES |
| 107 | + ensure_ticks_per_second(); |
| 108 | +#endif |
| 109 | + return PyStatus_Ok(); |
| 110 | +} |
| 111 | + |
| 112 | + |
65 | 113 | /* Forward declarations */
|
66 | 114 | static int pysleep(_PyTime_t timeout);
|
67 | 115 |
|
@@ -140,18 +188,8 @@ Return the current time in nanoseconds since the Epoch.");
|
140 | 188 | static int
|
141 | 189 | _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
142 | 190 | {
|
143 |
| - static int initialized = 0; |
144 |
| - |
145 |
| - if (!initialized) { |
146 |
| - initialized = 1; |
147 |
| - |
148 |
| - /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) |
149 |
| - above cannot overflow */ |
150 |
| - if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { |
151 |
| - PyErr_SetString(PyExc_OverflowError, |
152 |
| - "CLOCKS_PER_SEC is too large"); |
153 |
| - return -1; |
154 |
| - } |
| 191 | + if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) { |
| 192 | + return -1; |
155 | 193 | }
|
156 | 194 |
|
157 | 195 | if (info) {
|
@@ -1308,36 +1346,10 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
|
1308 | 1346 | struct tms t;
|
1309 | 1347 |
|
1310 | 1348 | if (times(&t) != (clock_t)-1) {
|
1311 |
| - static long ticks_per_second = -1; |
1312 |
| - |
1313 |
| - if (ticks_per_second == -1) { |
1314 |
| - long freq; |
1315 |
| -#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) |
1316 |
| - freq = sysconf(_SC_CLK_TCK); |
1317 |
| - if (freq < 1) { |
1318 |
| - freq = -1; |
1319 |
| - } |
1320 |
| -#elif defined(HZ) |
1321 |
| - freq = HZ; |
1322 |
| -#else |
1323 |
| - freq = 60; /* magic fallback value; may be bogus */ |
1324 |
| -#endif |
1325 |
| - |
1326 |
| - if (freq != -1) { |
1327 |
| - /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) |
1328 |
| - cannot overflow below */ |
1329 |
| -#if LONG_MAX > _PyTime_MAX / SEC_TO_NS |
1330 |
| - if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { |
1331 |
| - PyErr_SetString(PyExc_OverflowError, |
1332 |
| - "_SC_CLK_TCK is too large"); |
1333 |
| - return -1; |
1334 |
| - } |
1335 |
| -#endif |
1336 |
| - |
1337 |
| - ticks_per_second = freq; |
1338 |
| - } |
| 1349 | + assert(_PyRuntime.time.ticks_per_second_initialized); |
| 1350 | + if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) { |
| 1351 | + return -1; |
1339 | 1352 | }
|
1340 |
| - |
1341 | 1353 | if (ticks_per_second != -1) {
|
1342 | 1354 | if (info) {
|
1343 | 1355 | info->implementation = "times()";
|
|
0 commit comments