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.

406 lines
10 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 SEC_TO_MS 1000
  9. #define MS_TO_US 1000
  10. #define US_TO_NS 1000
  11. #define SEC_TO_US (SEC_TO_MS * MS_TO_US)
  12. static int
  13. pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
  14. {
  15. #ifdef MS_WINDOWS
  16. FILETIME system_time;
  17. ULARGE_INTEGER large;
  18. ULONGLONG microseconds;
  19. assert(info == NULL || raise);
  20. GetSystemTimeAsFileTime(&system_time);
  21. large.u.LowPart = system_time.dwLowDateTime;
  22. large.u.HighPart = system_time.dwHighDateTime;
  23. /* 11,644,473,600,000,000: number of microseconds between
  24. the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
  25. days). */
  26. microseconds = large.QuadPart / 10 - 11644473600000000;
  27. tp->tv_sec = microseconds / SEC_TO_US;
  28. tp->tv_usec = microseconds % SEC_TO_US;
  29. if (info) {
  30. DWORD timeAdjustment, timeIncrement;
  31. BOOL isTimeAdjustmentDisabled, ok;
  32. info->implementation = "GetSystemTimeAsFileTime()";
  33. info->monotonic = 0;
  34. ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
  35. &isTimeAdjustmentDisabled);
  36. if (!ok) {
  37. PyErr_SetFromWindowsErr(0);
  38. return -1;
  39. }
  40. info->resolution = timeIncrement * 1e-7;
  41. info->adjustable = 1;
  42. }
  43. #else /* MS_WINDOWS */
  44. int err;
  45. #ifdef HAVE_CLOCK_GETTIME
  46. struct timespec ts;
  47. #endif
  48. assert(info == NULL || raise);
  49. #ifdef HAVE_CLOCK_GETTIME
  50. err = clock_gettime(CLOCK_REALTIME, &ts);
  51. if (err) {
  52. if (raise)
  53. PyErr_SetFromErrno(PyExc_OSError);
  54. return -1;
  55. }
  56. tp->tv_sec = ts.tv_sec;
  57. tp->tv_usec = ts.tv_nsec / US_TO_NS;
  58. if (info) {
  59. struct timespec res;
  60. info->implementation = "clock_gettime(CLOCK_REALTIME)";
  61. info->monotonic = 0;
  62. info->adjustable = 1;
  63. if (clock_getres(CLOCK_REALTIME, &res) == 0)
  64. info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
  65. else
  66. info->resolution = 1e-9;
  67. }
  68. #else /* HAVE_CLOCK_GETTIME */
  69. /* test gettimeofday() */
  70. #ifdef GETTIMEOFDAY_NO_TZ
  71. err = gettimeofday(tp);
  72. #else
  73. err = gettimeofday(tp, (struct timezone *)NULL);
  74. #endif
  75. if (err) {
  76. if (raise)
  77. PyErr_SetFromErrno(PyExc_OSError);
  78. return -1;
  79. }
  80. if (info) {
  81. info->implementation = "gettimeofday()";
  82. info->resolution = 1e-6;
  83. info->monotonic = 0;
  84. info->adjustable = 1;
  85. }
  86. #endif /* !HAVE_CLOCK_GETTIME */
  87. #endif /* !MS_WINDOWS */
  88. assert(0 <= tp->tv_usec && tp->tv_usec < SEC_TO_US);
  89. return 0;
  90. }
  91. void
  92. _PyTime_gettimeofday(_PyTime_timeval *tp)
  93. {
  94. if (pygettimeofday(tp, NULL, 0) < 0) {
  95. /* cannot happen, _PyTime_Init() checks that pygettimeofday() works */
  96. assert(0);
  97. tp->tv_sec = 0;
  98. tp->tv_usec = 0;
  99. }
  100. }
  101. int
  102. _PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
  103. {
  104. return pygettimeofday(tp, info, 1);
  105. }
  106. static int
  107. pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
  108. {
  109. #ifdef Py_DEBUG
  110. static _PyTime_timeval last = {0, -1};
  111. #endif
  112. #if defined(MS_WINDOWS)
  113. ULONGLONG result;
  114. assert(info == NULL || raise);
  115. result = GetTickCount64();
  116. tp->tv_sec = result / SEC_TO_MS;
  117. tp->tv_usec = (result % SEC_TO_MS) * MS_TO_US;
  118. if (info) {
  119. DWORD timeAdjustment, timeIncrement;
  120. BOOL isTimeAdjustmentDisabled, ok;
  121. info->implementation = "GetTickCount64()";
  122. info->monotonic = 1;
  123. ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
  124. &isTimeAdjustmentDisabled);
  125. if (!ok) {
  126. PyErr_SetFromWindowsErr(0);
  127. return -1;
  128. }
  129. info->resolution = timeIncrement * 1e-7;
  130. info->adjustable = 0;
  131. }
  132. #elif defined(__APPLE__)
  133. static mach_timebase_info_data_t timebase;
  134. uint64_t time;
  135. if (timebase.denom == 0) {
  136. /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
  137. fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
  138. (void)mach_timebase_info(&timebase);
  139. }
  140. time = mach_absolute_time();
  141. /* nanoseconds => microseconds */
  142. time /= US_TO_NS;
  143. /* apply timebase factor */
  144. time *= timebase.numer;
  145. time /= timebase.denom;
  146. tp->tv_sec = time / SEC_TO_US;
  147. tp->tv_usec = time % SEC_TO_US;
  148. if (info) {
  149. info->implementation = "mach_absolute_time()";
  150. info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
  151. info->monotonic = 1;
  152. info->adjustable = 0;
  153. }
  154. #else
  155. struct timespec ts;
  156. #ifdef CLOCK_HIGHRES
  157. const clockid_t clk_id = CLOCK_HIGHRES;
  158. const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
  159. #else
  160. const clockid_t clk_id = CLOCK_MONOTONIC;
  161. const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
  162. #endif
  163. assert(info == NULL || raise);
  164. if (clock_gettime(clk_id, &ts) != 0) {
  165. if (raise) {
  166. PyErr_SetFromErrno(PyExc_OSError);
  167. return -1;
  168. }
  169. tp->tv_sec = 0;
  170. tp->tv_usec = 0;
  171. return -1;
  172. }
  173. if (info) {
  174. struct timespec res;
  175. info->monotonic = 1;
  176. info->implementation = implementation;
  177. info->adjustable = 0;
  178. if (clock_getres(clk_id, &res) != 0) {
  179. PyErr_SetFromErrno(PyExc_OSError);
  180. return -1;
  181. }
  182. info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
  183. }
  184. tp->tv_sec = ts.tv_sec;
  185. tp->tv_usec = ts.tv_nsec / US_TO_NS;
  186. #endif
  187. assert(0 <= tp->tv_usec && tp->tv_usec < SEC_TO_US);
  188. #ifdef Py_DEBUG
  189. /* monotonic clock cannot go backward */
  190. assert(last.tv_usec == -1
  191. || tp->tv_sec > last.tv_sec
  192. || (tp->tv_sec == last.tv_sec && tp->tv_usec >= last.tv_usec));
  193. last = *tp;
  194. #endif
  195. return 0;
  196. }
  197. void
  198. _PyTime_monotonic(_PyTime_timeval *tp)
  199. {
  200. if (pymonotonic(tp, NULL, 0) < 0) {
  201. /* cannot happen, _PyTime_Init() checks that pymonotonic() works */
  202. assert(0);
  203. tp->tv_sec = 0;
  204. tp->tv_usec = 0;
  205. }
  206. }
  207. int
  208. _PyTime_monotonic_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
  209. {
  210. return pymonotonic(tp, info, 1);
  211. }
  212. static void
  213. error_time_t_overflow(void)
  214. {
  215. PyErr_SetString(PyExc_OverflowError,
  216. "timestamp out of range for platform time_t");
  217. }
  218. time_t
  219. _PyLong_AsTime_t(PyObject *obj)
  220. {
  221. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  222. PY_LONG_LONG val;
  223. val = PyLong_AsLongLong(obj);
  224. #else
  225. long val;
  226. assert(sizeof(time_t) <= sizeof(long));
  227. val = PyLong_AsLong(obj);
  228. #endif
  229. if (val == -1 && PyErr_Occurred()) {
  230. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  231. error_time_t_overflow();
  232. return -1;
  233. }
  234. return (time_t)val;
  235. }
  236. PyObject *
  237. _PyLong_FromTime_t(time_t t)
  238. {
  239. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  240. return PyLong_FromLongLong((PY_LONG_LONG)t);
  241. #else
  242. assert(sizeof(time_t) <= sizeof(long));
  243. return PyLong_FromLong((long)t);
  244. #endif
  245. }
  246. static int
  247. _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
  248. double denominator, _PyTime_round_t round)
  249. {
  250. assert(denominator <= LONG_MAX);
  251. if (PyFloat_Check(obj)) {
  252. double d, intpart, err;
  253. /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
  254. volatile double floatpart;
  255. d = PyFloat_AsDouble(obj);
  256. floatpart = modf(d, &intpart);
  257. if (floatpart < 0) {
  258. floatpart = 1.0 + floatpart;
  259. intpart -= 1.0;
  260. }
  261. floatpart *= denominator;
  262. if (round == _PyTime_ROUND_UP) {
  263. if (intpart >= 0) {
  264. floatpart = ceil(floatpart);
  265. if (floatpart >= denominator) {
  266. floatpart = 0.0;
  267. intpart += 1.0;
  268. }
  269. }
  270. else {
  271. floatpart = floor(floatpart);
  272. }
  273. }
  274. *sec = (time_t)intpart;
  275. err = intpart - (double)*sec;
  276. if (err <= -1.0 || err >= 1.0) {
  277. error_time_t_overflow();
  278. return -1;
  279. }
  280. *numerator = (long)floatpart;
  281. return 0;
  282. }
  283. else {
  284. *sec = _PyLong_AsTime_t(obj);
  285. if (*sec == (time_t)-1 && PyErr_Occurred())
  286. return -1;
  287. *numerator = 0;
  288. return 0;
  289. }
  290. }
  291. int
  292. _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
  293. {
  294. if (PyFloat_Check(obj)) {
  295. double d, intpart, err;
  296. d = PyFloat_AsDouble(obj);
  297. if (round == _PyTime_ROUND_UP) {
  298. if (d >= 0)
  299. d = ceil(d);
  300. else
  301. d = floor(d);
  302. }
  303. (void)modf(d, &intpart);
  304. *sec = (time_t)intpart;
  305. err = intpart - (double)*sec;
  306. if (err <= -1.0 || err >= 1.0) {
  307. error_time_t_overflow();
  308. return -1;
  309. }
  310. return 0;
  311. }
  312. else {
  313. *sec = _PyLong_AsTime_t(obj);
  314. if (*sec == (time_t)-1 && PyErr_Occurred())
  315. return -1;
  316. return 0;
  317. }
  318. }
  319. int
  320. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
  321. _PyTime_round_t round)
  322. {
  323. return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
  324. }
  325. int
  326. _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
  327. _PyTime_round_t round)
  328. {
  329. return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
  330. }
  331. void
  332. _PyTime_AddDouble(_PyTime_timeval *tv, double interval, _PyTime_round_t round)
  333. {
  334. _PyTime_timeval tv2;
  335. double frac;
  336. frac = fmod(interval, 1.0);
  337. interval = floor(interval);
  338. tv2.tv_sec = (long)interval;
  339. tv2.tv_usec = (long)(frac*1e6);
  340. tv->tv_sec += tv2.tv_sec;
  341. tv->tv_usec += tv2.tv_usec;
  342. tv->tv_sec += (time_t)(tv->tv_usec / SEC_TO_US);
  343. tv->tv_usec %= SEC_TO_US;
  344. }
  345. int
  346. _PyTime_Init(void)
  347. {
  348. _PyTime_timeval tv;
  349. /* ensure that the system clock works */
  350. if (_PyTime_gettimeofday_info(&tv, NULL) < 0)
  351. return -1;
  352. /* ensure that the operating system provides a monotonic clock */
  353. if (_PyTime_monotonic_info(&tv, NULL) < 0)
  354. return -1;
  355. return 0;
  356. }