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.

231 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. info->adjustable = 1;
  43. }
  44. #else
  45. /* There are three ways to get the time:
  46. (1) gettimeofday() -- resolution in microseconds
  47. (2) ftime() -- resolution in milliseconds
  48. (3) time() -- resolution in seconds
  49. In all cases the return value in a timeval struct.
  50. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
  51. fail, so we fall back on ftime() or time().
  52. Note: clock resolution does not imply clock accuracy! */
  53. #ifdef HAVE_GETTIMEOFDAY
  54. int err;
  55. #ifdef GETTIMEOFDAY_NO_TZ
  56. err = gettimeofday(tp);
  57. #else
  58. err = gettimeofday(tp, (struct timezone *)NULL);
  59. #endif
  60. if (err == 0) {
  61. if (info) {
  62. info->implementation = "gettimeofday()";
  63. info->resolution = 1e-6;
  64. info->monotonic = 0;
  65. info->adjustable = 1;
  66. }
  67. return;
  68. }
  69. #endif /* HAVE_GETTIMEOFDAY */
  70. #if defined(HAVE_FTIME)
  71. {
  72. struct timeb t;
  73. ftime(&t);
  74. tp->tv_sec = t.time;
  75. tp->tv_usec = t.millitm * 1000;
  76. if (info) {
  77. info->implementation = "ftime()";
  78. info->resolution = 1e-3;
  79. info->monotonic = 0;
  80. info->adjustable = 1;
  81. }
  82. }
  83. #else /* !HAVE_FTIME */
  84. tp->tv_sec = time(NULL);
  85. tp->tv_usec = 0;
  86. if (info) {
  87. info->implementation = "time()";
  88. info->resolution = 1.0;
  89. info->monotonic = 0;
  90. info->adjustable = 1;
  91. }
  92. #endif /* !HAVE_FTIME */
  93. #endif /* MS_WINDOWS */
  94. }
  95. void
  96. _PyTime_gettimeofday(_PyTime_timeval *tp)
  97. {
  98. pygettimeofday(tp, NULL);
  99. }
  100. void
  101. _PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
  102. {
  103. pygettimeofday(tp, info);
  104. }
  105. static void
  106. error_time_t_overflow(void)
  107. {
  108. PyErr_SetString(PyExc_OverflowError,
  109. "timestamp out of range for platform time_t");
  110. }
  111. time_t
  112. _PyLong_AsTime_t(PyObject *obj)
  113. {
  114. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  115. PY_LONG_LONG val;
  116. val = PyLong_AsLongLong(obj);
  117. #else
  118. long val;
  119. assert(sizeof(time_t) <= sizeof(long));
  120. val = PyLong_AsLong(obj);
  121. #endif
  122. if (val == -1 && PyErr_Occurred()) {
  123. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  124. error_time_t_overflow();
  125. return -1;
  126. }
  127. return (time_t)val;
  128. }
  129. PyObject *
  130. _PyLong_FromTime_t(time_t t)
  131. {
  132. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  133. return PyLong_FromLongLong((PY_LONG_LONG)t);
  134. #else
  135. assert(sizeof(time_t) <= sizeof(long));
  136. return PyLong_FromLong((long)t);
  137. #endif
  138. }
  139. static int
  140. _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
  141. double denominator)
  142. {
  143. assert(denominator <= LONG_MAX);
  144. if (PyFloat_Check(obj)) {
  145. double d, intpart, err;
  146. /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
  147. volatile double floatpart;
  148. d = PyFloat_AsDouble(obj);
  149. floatpart = modf(d, &intpart);
  150. if (floatpart < 0) {
  151. floatpart = 1.0 + floatpart;
  152. intpart -= 1.0;
  153. }
  154. *sec = (time_t)intpart;
  155. err = intpart - (double)*sec;
  156. if (err <= -1.0 || err >= 1.0) {
  157. error_time_t_overflow();
  158. return -1;
  159. }
  160. floatpart *= denominator;
  161. *numerator = (long)floatpart;
  162. return 0;
  163. }
  164. else {
  165. *sec = _PyLong_AsTime_t(obj);
  166. if (*sec == (time_t)-1 && PyErr_Occurred())
  167. return -1;
  168. *numerator = 0;
  169. return 0;
  170. }
  171. }
  172. int
  173. _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec)
  174. {
  175. if (PyFloat_Check(obj)) {
  176. double d, intpart, err;
  177. d = PyFloat_AsDouble(obj);
  178. (void)modf(d, &intpart);
  179. *sec = (time_t)intpart;
  180. err = intpart - (double)*sec;
  181. if (err <= -1.0 || err >= 1.0) {
  182. error_time_t_overflow();
  183. return -1;
  184. }
  185. return 0;
  186. }
  187. else {
  188. *sec = _PyLong_AsTime_t(obj);
  189. if (*sec == (time_t)-1 && PyErr_Occurred())
  190. return -1;
  191. return 0;
  192. }
  193. }
  194. int
  195. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec)
  196. {
  197. return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9);
  198. }
  199. int
  200. _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec)
  201. {
  202. return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6);
  203. }
  204. void
  205. _PyTime_Init()
  206. {
  207. /* Do nothing. Needed to force linking. */
  208. }