You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

781 lines
18 KiB

  1. #include "Python.h"
  2. #ifdef MS_WINDOWS
  3. #include <windows.h>
  4. #endif
  5. #if defined(__APPLE__)
  6. #include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */
  7. #endif
  8. #define _PyTime_check_mul_overflow(a, b) \
  9. (assert(b > 0), \
  10. (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \
  11. || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a))
  12. /* To millisecond (10^-3) */
  13. #define SEC_TO_MS 1000
  14. /* To microseconds (10^-6) */
  15. #define MS_TO_US 1000
  16. #define SEC_TO_US (SEC_TO_MS * MS_TO_US)
  17. /* To nanoseconds (10^-9) */
  18. #define US_TO_NS 1000
  19. #define MS_TO_NS (MS_TO_US * US_TO_NS)
  20. #define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
  21. /* Conversion from nanoseconds */
  22. #define NS_TO_MS (1000 * 1000)
  23. #define NS_TO_US (1000)
  24. static void
  25. error_time_t_overflow(void)
  26. {
  27. PyErr_SetString(PyExc_OverflowError,
  28. "timestamp out of range for platform time_t");
  29. }
  30. time_t
  31. _PyLong_AsTime_t(PyObject *obj)
  32. {
  33. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  34. PY_LONG_LONG val;
  35. val = PyLong_AsLongLong(obj);
  36. #else
  37. long val;
  38. assert(sizeof(time_t) <= sizeof(long));
  39. val = PyLong_AsLong(obj);
  40. #endif
  41. if (val == -1 && PyErr_Occurred()) {
  42. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  43. error_time_t_overflow();
  44. return -1;
  45. }
  46. return (time_t)val;
  47. }
  48. PyObject *
  49. _PyLong_FromTime_t(time_t t)
  50. {
  51. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  52. return PyLong_FromLongLong((PY_LONG_LONG)t);
  53. #else
  54. assert(sizeof(time_t) <= sizeof(long));
  55. return PyLong_FromLong((long)t);
  56. #endif
  57. }
  58. /* Round to nearest with ties going to nearest even integer
  59. (_PyTime_ROUND_HALF_EVEN) */
  60. static double
  61. _PyTime_RoundHalfEven(double x)
  62. {
  63. double rounded = round(x);
  64. if (fabs(x-rounded) == 0.5)
  65. /* halfway case: round to even */
  66. rounded = 2.0*round(x/2.0);
  67. return rounded;
  68. }
  69. static double
  70. _PyTime_Round(double x, _PyTime_round_t round)
  71. {
  72. /* volatile avoids optimization changing how numbers are rounded */
  73. volatile double d;
  74. d = x;
  75. if (round == _PyTime_ROUND_HALF_EVEN)
  76. d = _PyTime_RoundHalfEven(d);
  77. else if (round == _PyTime_ROUND_CEILING)
  78. d = ceil(d);
  79. else
  80. d = floor(d);
  81. return d;
  82. }
  83. static int
  84. _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
  85. double denominator, _PyTime_round_t round)
  86. {
  87. double intpart, err;
  88. /* volatile avoids optimization changing how numbers are rounded */
  89. volatile double floatpart;
  90. floatpart = modf(d, &intpart);
  91. floatpart *= denominator;
  92. floatpart = _PyTime_Round(floatpart, round);
  93. if (floatpart >= denominator) {
  94. floatpart -= denominator;
  95. intpart += 1.0;
  96. }
  97. else if (floatpart < 0) {
  98. floatpart += denominator;
  99. intpart -= 1.0;
  100. }
  101. assert(0.0 <= floatpart && floatpart < denominator);
  102. *sec = (time_t)intpart;
  103. *numerator = (long)floatpart;
  104. err = intpart - (double)*sec;
  105. if (err <= -1.0 || err >= 1.0) {
  106. error_time_t_overflow();
  107. return -1;
  108. }
  109. return 0;
  110. }
  111. static int
  112. _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
  113. double denominator, _PyTime_round_t round)
  114. {
  115. assert(denominator <= (double)LONG_MAX);
  116. if (PyFloat_Check(obj)) {
  117. double d = PyFloat_AsDouble(obj);
  118. return _PyTime_DoubleToDenominator(d, sec, numerator,
  119. denominator, round);
  120. }
  121. else {
  122. *sec = _PyLong_AsTime_t(obj);
  123. *numerator = 0;
  124. if (*sec == (time_t)-1 && PyErr_Occurred())
  125. return -1;
  126. return 0;
  127. }
  128. }
  129. int
  130. _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
  131. {
  132. if (PyFloat_Check(obj)) {
  133. double intpart, err;
  134. /* volatile avoids optimization changing how numbers are rounded */
  135. volatile double d;
  136. d = PyFloat_AsDouble(obj);
  137. d = _PyTime_Round(d, round);
  138. (void)modf(d, &intpart);
  139. *sec = (time_t)intpart;
  140. err = intpart - (double)*sec;
  141. if (err <= -1.0 || err >= 1.0) {
  142. error_time_t_overflow();
  143. return -1;
  144. }
  145. return 0;
  146. }
  147. else {
  148. *sec = _PyLong_AsTime_t(obj);
  149. if (*sec == (time_t)-1 && PyErr_Occurred())
  150. return -1;
  151. return 0;
  152. }
  153. }
  154. int
  155. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
  156. _PyTime_round_t round)
  157. {
  158. int res;
  159. res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
  160. assert(0 <= *nsec && *nsec < SEC_TO_NS);
  161. return res;
  162. }
  163. int
  164. _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
  165. _PyTime_round_t round)
  166. {
  167. int res;
  168. res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
  169. assert(0 <= *usec && *usec < SEC_TO_US);
  170. return res;
  171. }
  172. static void
  173. _PyTime_overflow(void)
  174. {
  175. PyErr_SetString(PyExc_OverflowError,
  176. "timestamp too large to convert to C _PyTime_t");
  177. }
  178. _PyTime_t
  179. _PyTime_FromSeconds(int seconds)
  180. {
  181. _PyTime_t t;
  182. t = (_PyTime_t)seconds;
  183. /* ensure that integer overflow cannot happen, int type should have 32
  184. bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30
  185. bits). */
  186. assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS)
  187. || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS));
  188. t *= SEC_TO_NS;
  189. return t;
  190. }
  191. _PyTime_t
  192. _PyTime_FromNanoseconds(PY_LONG_LONG ns)
  193. {
  194. _PyTime_t t;
  195. assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
  196. t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
  197. return t;
  198. }
  199. #ifdef HAVE_CLOCK_GETTIME
  200. static int
  201. _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise)
  202. {
  203. _PyTime_t t;
  204. int res = 0;
  205. assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t));
  206. t = (_PyTime_t)ts->tv_sec;
  207. if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
  208. if (raise)
  209. _PyTime_overflow();
  210. res = -1;
  211. }
  212. t = t * SEC_TO_NS;
  213. t += ts->tv_nsec;
  214. *tp = t;
  215. return res;
  216. }
  217. #elif !defined(MS_WINDOWS)
  218. static int
  219. _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise)
  220. {
  221. _PyTime_t t;
  222. int res = 0;
  223. assert(sizeof(tv->tv_sec) <= sizeof(_PyTime_t));
  224. t = (_PyTime_t)tv->tv_sec;
  225. if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
  226. if (raise)
  227. _PyTime_overflow();
  228. res = -1;
  229. }
  230. t = t * SEC_TO_NS;
  231. t += (_PyTime_t)tv->tv_usec * US_TO_NS;
  232. *tp = t;
  233. return res;
  234. }
  235. #endif
  236. static int
  237. _PyTime_FromFloatObject(_PyTime_t *t, double value, _PyTime_round_t round,
  238. long unit_to_ns)
  239. {
  240. double err;
  241. /* volatile avoids optimization changing how numbers are rounded */
  242. volatile double d;
  243. /* convert to a number of nanoseconds */
  244. d = value;
  245. d *= (double)unit_to_ns;
  246. d = _PyTime_Round(d, round);
  247. *t = (_PyTime_t)d;
  248. err = d - (double)*t;
  249. if (fabs(err) >= 1.0) {
  250. _PyTime_overflow();
  251. return -1;
  252. }
  253. return 0;
  254. }
  255. static int
  256. _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
  257. long unit_to_ns)
  258. {
  259. if (PyFloat_Check(obj)) {
  260. double d;
  261. d = PyFloat_AsDouble(obj);
  262. return _PyTime_FromFloatObject(t, d, round, unit_to_ns);
  263. }
  264. else {
  265. #ifdef HAVE_LONG_LONG
  266. PY_LONG_LONG sec;
  267. assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
  268. sec = PyLong_AsLongLong(obj);
  269. #else
  270. long sec;
  271. assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
  272. sec = PyLong_AsLong(obj);
  273. #endif
  274. if (sec == -1 && PyErr_Occurred()) {
  275. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  276. _PyTime_overflow();
  277. return -1;
  278. }
  279. if (_PyTime_check_mul_overflow(sec, unit_to_ns)) {
  280. _PyTime_overflow();
  281. return -1;
  282. }
  283. *t = sec * unit_to_ns;
  284. return 0;
  285. }
  286. }
  287. int
  288. _PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
  289. {
  290. return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
  291. }
  292. int
  293. _PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
  294. {
  295. return _PyTime_FromObject(t, obj, round, MS_TO_NS);
  296. }
  297. double
  298. _PyTime_AsSecondsDouble(_PyTime_t t)
  299. {
  300. /* volatile avoids optimization changing how numbers are rounded */
  301. volatile double d;
  302. if (t % SEC_TO_NS == 0) {
  303. _PyTime_t secs;
  304. /* Divide using integers to avoid rounding issues on the integer part.
  305. 1e-9 cannot be stored exactly in IEEE 64-bit. */
  306. secs = t / SEC_TO_NS;
  307. d = (double)secs;
  308. }
  309. else {
  310. d = (double)t;
  311. d /= 1e9;
  312. }
  313. return d;
  314. }
  315. PyObject *
  316. _PyTime_AsNanosecondsObject(_PyTime_t t)
  317. {
  318. #ifdef HAVE_LONG_LONG
  319. assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
  320. return PyLong_FromLongLong((PY_LONG_LONG)t);
  321. #else
  322. assert(sizeof(long) >= sizeof(_PyTime_t));
  323. return PyLong_FromLong((long)t);
  324. #endif
  325. }
  326. static _PyTime_t
  327. _PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
  328. const _PyTime_round_t round)
  329. {
  330. assert(k > 1);
  331. if (round == _PyTime_ROUND_HALF_EVEN) {
  332. _PyTime_t x, r, abs_r;
  333. x = t / k;
  334. r = t % k;
  335. abs_r = Py_ABS(r);
  336. if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
  337. if (t >= 0)
  338. x++;
  339. else
  340. x--;
  341. }
  342. return x;
  343. }
  344. else if (round == _PyTime_ROUND_CEILING) {
  345. if (t >= 0)
  346. return (t + k - 1) / k;
  347. else
  348. return t / k;
  349. }
  350. else {
  351. if (t >= 0)
  352. return t / k;
  353. else
  354. return (t - (k - 1)) / k;
  355. }
  356. }
  357. _PyTime_t
  358. _PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
  359. {
  360. return _PyTime_Divide(t, NS_TO_MS, round);
  361. }
  362. _PyTime_t
  363. _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
  364. {
  365. return _PyTime_Divide(t, NS_TO_US, round);
  366. }
  367. static int
  368. _PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us,
  369. _PyTime_round_t round)
  370. {
  371. _PyTime_t secs, ns;
  372. int usec;
  373. int res = 0;
  374. secs = t / SEC_TO_NS;
  375. ns = t % SEC_TO_NS;
  376. usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
  377. if (usec < 0) {
  378. usec += SEC_TO_US;
  379. if (secs != _PyTime_MIN)
  380. secs -= 1;
  381. else
  382. res = -1;
  383. }
  384. else if (usec >= SEC_TO_US) {
  385. usec -= SEC_TO_US;
  386. if (secs != _PyTime_MAX)
  387. secs += 1;
  388. else
  389. res = -1;
  390. }
  391. assert(0 <= usec && usec < SEC_TO_US);
  392. *p_secs = secs;
  393. *p_us = usec;
  394. return res;
  395. }
  396. static int
  397. _PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv,
  398. _PyTime_round_t round, int raise)
  399. {
  400. _PyTime_t secs, secs2;
  401. int us;
  402. int res;
  403. res = _PyTime_AsTimeval_impl(t, &secs, &us, round);
  404. #ifdef MS_WINDOWS
  405. tv->tv_sec = (long)secs;
  406. #else
  407. tv->tv_sec = secs;
  408. #endif
  409. tv->tv_usec = us;
  410. secs2 = (_PyTime_t)tv->tv_sec;
  411. if (res < 0 || secs2 != secs) {
  412. if (raise)
  413. error_time_t_overflow();
  414. return -1;
  415. }
  416. return 0;
  417. }
  418. int
  419. _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
  420. {
  421. return _PyTime_AsTimevalStruct_impl(t, tv, round, 1);
  422. }
  423. int
  424. _PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
  425. {
  426. return _PyTime_AsTimevalStruct_impl(t, tv, round, 0);
  427. }
  428. int
  429. _PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
  430. _PyTime_round_t round)
  431. {
  432. _PyTime_t secs;
  433. int res;
  434. res = _PyTime_AsTimeval_impl(t, &secs, us, round);
  435. *p_secs = secs;
  436. if (res < 0 || (_PyTime_t)*p_secs != secs) {
  437. error_time_t_overflow();
  438. return -1;
  439. }
  440. return 0;
  441. }
  442. #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
  443. int
  444. _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
  445. {
  446. _PyTime_t secs, nsec;
  447. secs = t / SEC_TO_NS;
  448. nsec = t % SEC_TO_NS;
  449. if (nsec < 0) {
  450. nsec += SEC_TO_NS;
  451. secs -= 1;
  452. }
  453. ts->tv_sec = (time_t)secs;
  454. assert(0 <= nsec && nsec < SEC_TO_NS);
  455. ts->tv_nsec = nsec;
  456. if ((_PyTime_t)ts->tv_sec != secs) {
  457. error_time_t_overflow();
  458. return -1;
  459. }
  460. return 0;
  461. }
  462. #endif
  463. static int
  464. pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
  465. {
  466. #ifdef MS_WINDOWS
  467. FILETIME system_time;
  468. ULARGE_INTEGER large;
  469. assert(info == NULL || raise);
  470. GetSystemTimeAsFileTime(&system_time);
  471. large.u.LowPart = system_time.dwLowDateTime;
  472. large.u.HighPart = system_time.dwHighDateTime;
  473. /* 11,644,473,600,000,000,000: number of nanoseconds between
  474. the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
  475. days). */
  476. *tp = large.QuadPart * 100 - 11644473600000000000;
  477. if (info) {
  478. DWORD timeAdjustment, timeIncrement;
  479. BOOL isTimeAdjustmentDisabled, ok;
  480. info->implementation = "GetSystemTimeAsFileTime()";
  481. info->monotonic = 0;
  482. ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
  483. &isTimeAdjustmentDisabled);
  484. if (!ok) {
  485. PyErr_SetFromWindowsErr(0);
  486. return -1;
  487. }
  488. info->resolution = timeIncrement * 1e-7;
  489. info->adjustable = 1;
  490. }
  491. #else /* MS_WINDOWS */
  492. int err;
  493. #ifdef HAVE_CLOCK_GETTIME
  494. struct timespec ts;
  495. #else
  496. struct timeval tv;
  497. #endif
  498. assert(info == NULL || raise);
  499. #ifdef HAVE_CLOCK_GETTIME
  500. err = clock_gettime(CLOCK_REALTIME, &ts);
  501. if (err) {
  502. if (raise)
  503. PyErr_SetFromErrno(PyExc_OSError);
  504. return -1;
  505. }
  506. if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
  507. return -1;
  508. if (info) {
  509. struct timespec res;
  510. info->implementation = "clock_gettime(CLOCK_REALTIME)";
  511. info->monotonic = 0;
  512. info->adjustable = 1;
  513. if (clock_getres(CLOCK_REALTIME, &res) == 0)
  514. info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
  515. else
  516. info->resolution = 1e-9;
  517. }
  518. #else /* HAVE_CLOCK_GETTIME */
  519. /* test gettimeofday() */
  520. #ifdef GETTIMEOFDAY_NO_TZ
  521. err = gettimeofday(&tv);
  522. #else
  523. err = gettimeofday(&tv, (struct timezone *)NULL);
  524. #endif
  525. if (err) {
  526. if (raise)
  527. PyErr_SetFromErrno(PyExc_OSError);
  528. return -1;
  529. }
  530. if (_PyTime_FromTimeval(tp, &tv, raise) < 0)
  531. return -1;
  532. if (info) {
  533. info->implementation = "gettimeofday()";
  534. info->resolution = 1e-6;
  535. info->monotonic = 0;
  536. info->adjustable = 1;
  537. }
  538. #endif /* !HAVE_CLOCK_GETTIME */
  539. #endif /* !MS_WINDOWS */
  540. return 0;
  541. }
  542. _PyTime_t
  543. _PyTime_GetSystemClock(void)
  544. {
  545. _PyTime_t t;
  546. if (pygettimeofday_new(&t, NULL, 0) < 0) {
  547. /* should not happen, _PyTime_Init() checked the clock at startup */
  548. assert(0);
  549. /* use a fixed value instead of a random value from the stack */
  550. t = 0;
  551. }
  552. return t;
  553. }
  554. int
  555. _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
  556. {
  557. return pygettimeofday_new(t, info, 1);
  558. }
  559. static int
  560. pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
  561. {
  562. #if defined(MS_WINDOWS)
  563. ULONGLONG ticks;
  564. _PyTime_t t;
  565. assert(info == NULL || raise);
  566. ticks = GetTickCount64();
  567. assert(sizeof(ticks) <= sizeof(_PyTime_t));
  568. t = (_PyTime_t)ticks;
  569. if (_PyTime_check_mul_overflow(t, MS_TO_NS)) {
  570. if (raise) {
  571. _PyTime_overflow();
  572. return -1;
  573. }
  574. /* Hello, time traveler! */
  575. assert(0);
  576. }
  577. *tp = t * MS_TO_NS;
  578. if (info) {
  579. DWORD timeAdjustment, timeIncrement;
  580. BOOL isTimeAdjustmentDisabled, ok;
  581. info->implementation = "GetTickCount64()";
  582. info->monotonic = 1;
  583. ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
  584. &isTimeAdjustmentDisabled);
  585. if (!ok) {
  586. PyErr_SetFromWindowsErr(0);
  587. return -1;
  588. }
  589. info->resolution = timeIncrement * 1e-7;
  590. info->adjustable = 0;
  591. }
  592. #elif defined(__APPLE__)
  593. static mach_timebase_info_data_t timebase;
  594. uint64_t time;
  595. if (timebase.denom == 0) {
  596. /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
  597. fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
  598. (void)mach_timebase_info(&timebase);
  599. }
  600. time = mach_absolute_time();
  601. /* apply timebase factor */
  602. time *= timebase.numer;
  603. time /= timebase.denom;
  604. *tp = time;
  605. if (info) {
  606. info->implementation = "mach_absolute_time()";
  607. info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
  608. info->monotonic = 1;
  609. info->adjustable = 0;
  610. }
  611. #else
  612. struct timespec ts;
  613. #ifdef CLOCK_HIGHRES
  614. const clockid_t clk_id = CLOCK_HIGHRES;
  615. const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
  616. #else
  617. const clockid_t clk_id = CLOCK_MONOTONIC;
  618. const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
  619. #endif
  620. assert(info == NULL || raise);
  621. if (clock_gettime(clk_id, &ts) != 0) {
  622. if (raise) {
  623. PyErr_SetFromErrno(PyExc_OSError);
  624. return -1;
  625. }
  626. return -1;
  627. }
  628. if (info) {
  629. struct timespec res;
  630. info->monotonic = 1;
  631. info->implementation = implementation;
  632. info->adjustable = 0;
  633. if (clock_getres(clk_id, &res) != 0) {
  634. PyErr_SetFromErrno(PyExc_OSError);
  635. return -1;
  636. }
  637. info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
  638. }
  639. if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
  640. return -1;
  641. #endif
  642. return 0;
  643. }
  644. _PyTime_t
  645. _PyTime_GetMonotonicClock(void)
  646. {
  647. _PyTime_t t;
  648. if (pymonotonic(&t, NULL, 0) < 0) {
  649. /* should not happen, _PyTime_Init() checked that monotonic clock at
  650. startup */
  651. assert(0);
  652. /* use a fixed value instead of a random value from the stack */
  653. t = 0;
  654. }
  655. return t;
  656. }
  657. int
  658. _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
  659. {
  660. return pymonotonic(tp, info, 1);
  661. }
  662. int
  663. _PyTime_Init(void)
  664. {
  665. _PyTime_t t;
  666. /* ensure that the system clock works */
  667. if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
  668. return -1;
  669. /* ensure that the operating system provides a monotonic clock */
  670. if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
  671. return -1;
  672. /* check that _PyTime_FromSeconds() cannot overflow */
  673. assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS);
  674. assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS);
  675. return 0;
  676. }