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.

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