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.

234 lines
5.9 KiB

14 years ago
  1. #include "Python.h"
  2. #ifdef MS_WINDOWS
  3. #include <windows.h>
  4. #endif
  5. #if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
  6. /*
  7. * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter
  8. * might fail on some platforms. This fallback is unwanted on MacOSX because
  9. * that makes it impossible to use a binary build on OSX 10.4 on earlier
  10. * releases of the OS. Therefore claim we don't support ftime.
  11. */
  12. # undef HAVE_FTIME
  13. #endif
  14. #if defined(HAVE_FTIME) && !defined(MS_WINDOWS)
  15. #include <sys/timeb.h>
  16. extern int ftime(struct timeb *);
  17. #endif
  18. static void
  19. pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info)
  20. {
  21. #ifdef MS_WINDOWS
  22. FILETIME system_time;
  23. ULARGE_INTEGER large;
  24. ULONGLONG microseconds;
  25. GetSystemTimeAsFileTime(&system_time);
  26. large.u.LowPart = system_time.dwLowDateTime;
  27. large.u.HighPart = system_time.dwHighDateTime;
  28. /* 11,644,473,600,000,000: number of microseconds between
  29. the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
  30. days). */
  31. microseconds = large.QuadPart / 10 - 11644473600000000;
  32. tp->tv_sec = microseconds / 1000000;
  33. tp->tv_usec = microseconds % 1000000;
  34. if (info) {
  35. DWORD timeAdjustment, timeIncrement;
  36. BOOL isTimeAdjustmentDisabled;
  37. info->implementation = "GetSystemTimeAsFileTime()";
  38. info->monotonic = 0;
  39. (void) GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
  40. &isTimeAdjustmentDisabled);
  41. info->resolution = timeIncrement * 1e-7;
  42. if (isTimeAdjustmentDisabled)
  43. info->adjusted = 0;
  44. else
  45. info->adjusted = 1;
  46. }
  47. #else
  48. /* There are three ways to get the time:
  49. (1) gettimeofday() -- resolution in microseconds
  50. (2) ftime() -- resolution in milliseconds
  51. (3) time() -- resolution in seconds
  52. In all cases the return value in a timeval struct.
  53. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
  54. fail, so we fall back on ftime() or time().
  55. Note: clock resolution does not imply clock accuracy! */
  56. #ifdef HAVE_GETTIMEOFDAY
  57. int err;
  58. #ifdef GETTIMEOFDAY_NO_TZ
  59. err = gettimeofday(tp);
  60. #else
  61. err = gettimeofday(tp, (struct timezone *)NULL);
  62. #endif
  63. if (err == 0) {
  64. if (info) {
  65. info->implementation = "gettimeofday()";
  66. info->resolution = 1e-6;
  67. info->monotonic = 0;
  68. info->adjusted = 1;
  69. }
  70. return;
  71. }
  72. #endif /* HAVE_GETTIMEOFDAY */
  73. #if defined(HAVE_FTIME)
  74. {
  75. struct timeb t;
  76. ftime(&t);
  77. tp->tv_sec = t.time;
  78. tp->tv_usec = t.millitm * 1000;
  79. if (info) {
  80. info->implementation = "ftime()";
  81. info->resolution = 1e-3;
  82. info->monotonic = 0;
  83. info->adjusted = 1;
  84. }
  85. }
  86. #else /* !HAVE_FTIME */
  87. tp->tv_sec = time(NULL);
  88. tp->tv_usec = 0;
  89. if (info) {
  90. info->implementation = "time()";
  91. info->resolution = 1.0;
  92. info->monotonic = 0;
  93. info->adjusted = 1;
  94. }
  95. #endif /* !HAVE_FTIME */
  96. #endif /* MS_WINDOWS */
  97. }
  98. void
  99. _PyTime_gettimeofday(_PyTime_timeval *tp)
  100. {
  101. pygettimeofday(tp, NULL);
  102. }
  103. void
  104. _PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
  105. {
  106. pygettimeofday(tp, info);
  107. }
  108. static void
  109. error_time_t_overflow(void)
  110. {
  111. PyErr_SetString(PyExc_OverflowError,
  112. "timestamp out of range for platform time_t");
  113. }
  114. time_t
  115. _PyLong_AsTime_t(PyObject *obj)
  116. {
  117. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  118. PY_LONG_LONG val;
  119. val = PyLong_AsLongLong(obj);
  120. #else
  121. long val;
  122. assert(sizeof(time_t) <= sizeof(long));
  123. val = PyLong_AsLong(obj);
  124. #endif
  125. if (val == -1 && PyErr_Occurred()) {
  126. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  127. error_time_t_overflow();
  128. return -1;
  129. }
  130. return (time_t)val;
  131. }
  132. PyObject *
  133. _PyLong_FromTime_t(time_t t)
  134. {
  135. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  136. return PyLong_FromLongLong((PY_LONG_LONG)t);
  137. #else
  138. assert(sizeof(time_t) <= sizeof(long));
  139. return PyLong_FromLong((long)t);
  140. #endif
  141. }
  142. static int
  143. _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
  144. double denominator)
  145. {
  146. assert(denominator <= LONG_MAX);
  147. if (PyFloat_Check(obj)) {
  148. double d, intpart, err;
  149. /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
  150. volatile double floatpart;
  151. d = PyFloat_AsDouble(obj);
  152. floatpart = modf(d, &intpart);
  153. if (floatpart < 0) {
  154. floatpart = 1.0 + floatpart;
  155. intpart -= 1.0;
  156. }
  157. *sec = (time_t)intpart;
  158. err = intpart - (double)*sec;
  159. if (err <= -1.0 || err >= 1.0) {
  160. error_time_t_overflow();
  161. return -1;
  162. }
  163. floatpart *= denominator;
  164. *numerator = (long)floatpart;
  165. return 0;
  166. }
  167. else {
  168. *sec = _PyLong_AsTime_t(obj);
  169. if (*sec == (time_t)-1 && PyErr_Occurred())
  170. return -1;
  171. *numerator = 0;
  172. return 0;
  173. }
  174. }
  175. int
  176. _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec)
  177. {
  178. if (PyFloat_Check(obj)) {
  179. double d, intpart, err;
  180. d = PyFloat_AsDouble(obj);
  181. (void)modf(d, &intpart);
  182. *sec = (time_t)intpart;
  183. err = intpart - (double)*sec;
  184. if (err <= -1.0 || err >= 1.0) {
  185. error_time_t_overflow();
  186. return -1;
  187. }
  188. return 0;
  189. }
  190. else {
  191. *sec = _PyLong_AsTime_t(obj);
  192. if (*sec == (time_t)-1 && PyErr_Occurred())
  193. return -1;
  194. return 0;
  195. }
  196. }
  197. int
  198. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec)
  199. {
  200. return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9);
  201. }
  202. int
  203. _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec)
  204. {
  205. return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6);
  206. }
  207. void
  208. _PyTime_Init()
  209. {
  210. /* Do nothing. Needed to force linking. */
  211. }