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.

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