blob: 8c6771baf38d337688a308aa327d1778dfb3d794 [file] [log] [blame]
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00001#include "Python.h"
Victor Stinner09225b72012-02-07 23:41:01 +01002#ifdef MS_WINDOWS
3#include <windows.h>
4#endif
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00005
Victor Stinnerae586492014-09-02 23:18:25 +02006#if defined(__APPLE__)
7#include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */
8#endif
9
Victor Stinnercb29f012015-03-27 13:31:18 +010010/* To millisecond (10^-3) */
Victor Stinner580ef132015-03-20 01:55:04 +010011#define SEC_TO_MS 1000
Victor Stinner580ef132015-03-20 01:55:04 +010012
Victor Stinnercb29f012015-03-27 13:31:18 +010013/* To microseconds (10^-6) */
14#define MS_TO_US 1000
Victor Stinner580ef132015-03-20 01:55:04 +010015#define SEC_TO_US (SEC_TO_MS * MS_TO_US)
16
Victor Stinnercb29f012015-03-27 13:31:18 +010017/* To nanoseconds (10^-9) */
18#define US_TO_NS 1000
19#define MS_TO_NS (MS_TO_US * US_TO_NS)
20#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
21
Victor Stinner00111242014-08-29 16:31:59 +020022static int
23pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000024{
Victor Stinner09225b72012-02-07 23:41:01 +010025#ifdef MS_WINDOWS
26 FILETIME system_time;
27 ULARGE_INTEGER large;
Victor Stinner4195b5c2012-02-08 23:03:19 +010028 ULONGLONG microseconds;
Victor Stinner09225b72012-02-07 23:41:01 +010029
Victor Stinner00111242014-08-29 16:31:59 +020030 assert(info == NULL || raise);
31
Victor Stinner09225b72012-02-07 23:41:01 +010032 GetSystemTimeAsFileTime(&system_time);
33 large.u.LowPart = system_time.dwLowDateTime;
34 large.u.HighPart = system_time.dwHighDateTime;
Victor Stinner4195b5c2012-02-08 23:03:19 +010035 /* 11,644,473,600,000,000: number of microseconds between
Victor Stinner09225b72012-02-07 23:41:01 +010036 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
37 days). */
Victor Stinner4195b5c2012-02-08 23:03:19 +010038 microseconds = large.QuadPart / 10 - 11644473600000000;
Victor Stinner580ef132015-03-20 01:55:04 +010039 tp->tv_sec = microseconds / SEC_TO_US;
40 tp->tv_usec = microseconds % SEC_TO_US;
Victor Stinnerec895392012-04-29 02:41:27 +020041 if (info) {
42 DWORD timeAdjustment, timeIncrement;
Victor Stinner00111242014-08-29 16:31:59 +020043 BOOL isTimeAdjustmentDisabled, ok;
Victor Stinnerec895392012-04-29 02:41:27 +020044
45 info->implementation = "GetSystemTimeAsFileTime()";
Benjamin Peterson49a69e42012-05-01 09:38:34 -040046 info->monotonic = 0;
Victor Stinner00111242014-08-29 16:31:59 +020047 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
48 &isTimeAdjustmentDisabled);
49 if (!ok) {
50 PyErr_SetFromWindowsErr(0);
51 return -1;
52 }
Victor Stinnerec895392012-04-29 02:41:27 +020053 info->resolution = timeIncrement * 1e-7;
Victor Stinner2b89fdf2012-06-12 22:46:37 +020054 info->adjustable = 1;
Victor Stinnerec895392012-04-29 02:41:27 +020055 }
Victor Stinner09225b72012-02-07 23:41:01 +010056
Victor Stinner00111242014-08-29 16:31:59 +020057#else /* MS_WINDOWS */
Victor Stinnerec895392012-04-29 02:41:27 +020058 int err;
Victor Stinner7efb8332014-08-29 15:41:08 +020059#ifdef HAVE_CLOCK_GETTIME
60 struct timespec ts;
61#endif
Victor Stinner7efb8332014-08-29 15:41:08 +020062
Victor Stinner00111242014-08-29 16:31:59 +020063 assert(info == NULL || raise);
64
Victor Stinner7efb8332014-08-29 15:41:08 +020065#ifdef HAVE_CLOCK_GETTIME
Victor Stinner00111242014-08-29 16:31:59 +020066 err = clock_gettime(CLOCK_REALTIME, &ts);
67 if (err) {
68 if (raise)
69 PyErr_SetFromErrno(PyExc_OSError);
70 return -1;
Victor Stinner7efb8332014-08-29 15:41:08 +020071 }
Victor Stinner00111242014-08-29 16:31:59 +020072 tp->tv_sec = ts.tv_sec;
Victor Stinner580ef132015-03-20 01:55:04 +010073 tp->tv_usec = ts.tv_nsec / US_TO_NS;
Victor Stinner00111242014-08-29 16:31:59 +020074
75 if (info) {
76 struct timespec res;
77 info->implementation = "clock_gettime(CLOCK_REALTIME)";
78 info->monotonic = 0;
79 info->adjustable = 1;
80 if (clock_getres(CLOCK_REALTIME, &res) == 0)
81 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
82 else
83 info->resolution = 1e-9;
84 }
Victor Stinner00111242014-08-29 16:31:59 +020085#else /* HAVE_CLOCK_GETTIME */
Victor Stinner7efb8332014-08-29 15:41:08 +020086
87 /* test gettimeofday() */
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000088#ifdef GETTIMEOFDAY_NO_TZ
Victor Stinnerec895392012-04-29 02:41:27 +020089 err = gettimeofday(tp);
90#else
91 err = gettimeofday(tp, (struct timezone *)NULL);
92#endif
Victor Stinner00111242014-08-29 16:31:59 +020093 if (err) {
94 if (raise)
95 PyErr_SetFromErrno(PyExc_OSError);
96 return -1;
Victor Stinnerec895392012-04-29 02:41:27 +020097 }
Victor Stinner00111242014-08-29 16:31:59 +020098
99 if (info) {
100 info->implementation = "gettimeofday()";
101 info->resolution = 1e-6;
102 info->monotonic = 0;
103 info->adjustable = 1;
104 }
Victor Stinner00111242014-08-29 16:31:59 +0200105#endif /* !HAVE_CLOCK_GETTIME */
106#endif /* !MS_WINDOWS */
Victor Stinner580ef132015-03-20 01:55:04 +0100107 assert(0 <= tp->tv_usec && tp->tv_usec < SEC_TO_US);
Victor Stinner9bb758c2014-09-02 23:01:40 +0200108 return 0;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000109}
110
Victor Stinnerec895392012-04-29 02:41:27 +0200111void
112_PyTime_gettimeofday(_PyTime_timeval *tp)
113{
Victor Stinner00111242014-08-29 16:31:59 +0200114 if (pygettimeofday(tp, NULL, 0) < 0) {
115 /* cannot happen, _PyTime_Init() checks that pygettimeofday() works */
116 assert(0);
117 tp->tv_sec = 0;
118 tp->tv_usec = 0;
119 }
Victor Stinnerec895392012-04-29 02:41:27 +0200120}
121
Victor Stinner5d272cc2012-03-13 13:35:55 +0100122static void
123error_time_t_overflow(void)
Victor Stinner643cd682012-03-02 22:54:03 +0100124{
Victor Stinner5d272cc2012-03-13 13:35:55 +0100125 PyErr_SetString(PyExc_OverflowError,
126 "timestamp out of range for platform time_t");
127}
128
Larry Hastings76ad59b2012-05-03 00:30:07 -0700129time_t
Victor Stinner5d272cc2012-03-13 13:35:55 +0100130_PyLong_AsTime_t(PyObject *obj)
131{
132#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
133 PY_LONG_LONG val;
134 val = PyLong_AsLongLong(obj);
135#else
136 long val;
137 assert(sizeof(time_t) <= sizeof(long));
138 val = PyLong_AsLong(obj);
139#endif
140 if (val == -1 && PyErr_Occurred()) {
141 if (PyErr_ExceptionMatches(PyExc_OverflowError))
142 error_time_t_overflow();
143 return -1;
144 }
145 return (time_t)val;
146}
147
Larry Hastings6fe20b32012-04-19 15:07:49 -0700148PyObject *
149_PyLong_FromTime_t(time_t t)
150{
151#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
152 return PyLong_FromLongLong((PY_LONG_LONG)t);
153#else
154 assert(sizeof(time_t) <= sizeof(long));
155 return PyLong_FromLong((long)t);
156#endif
157}
158
Victor Stinner5d272cc2012-03-13 13:35:55 +0100159static int
160_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
Victor Stinner3c1b3792014-02-17 00:02:43 +0100161 double denominator, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100162{
163 assert(denominator <= LONG_MAX);
Victor Stinner643cd682012-03-02 22:54:03 +0100164 if (PyFloat_Check(obj)) {
Victor Stinnerbd273c12012-03-13 19:12:23 +0100165 double d, intpart, err;
166 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
167 volatile double floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +0100168
169 d = PyFloat_AsDouble(obj);
170 floatpart = modf(d, &intpart);
171 if (floatpart < 0) {
172 floatpart = 1.0 + floatpart;
173 intpart -= 1.0;
174 }
175
Victor Stinner3c1b3792014-02-17 00:02:43 +0100176 floatpart *= denominator;
177 if (round == _PyTime_ROUND_UP) {
178 if (intpart >= 0) {
179 floatpart = ceil(floatpart);
180 if (floatpart >= denominator) {
181 floatpart = 0.0;
182 intpart += 1.0;
183 }
184 }
185 else {
186 floatpart = floor(floatpart);
187 }
188 }
189
Victor Stinner643cd682012-03-02 22:54:03 +0100190 *sec = (time_t)intpart;
191 err = intpart - (double)*sec;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100192 if (err <= -1.0 || err >= 1.0) {
193 error_time_t_overflow();
194 return -1;
195 }
Victor Stinner643cd682012-03-02 22:54:03 +0100196
Victor Stinner5d272cc2012-03-13 13:35:55 +0100197 *numerator = (long)floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +0100198 return 0;
199 }
200 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +0100201 *sec = _PyLong_AsTime_t(obj);
202 if (*sec == (time_t)-1 && PyErr_Occurred())
203 return -1;
204 *numerator = 0;
Victor Stinner643cd682012-03-02 22:54:03 +0100205 return 0;
206 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100207}
Victor Stinner643cd682012-03-02 22:54:03 +0100208
Victor Stinner5d272cc2012-03-13 13:35:55 +0100209int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100210_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100211{
212 if (PyFloat_Check(obj)) {
213 double d, intpart, err;
214
Victor Stinner5d272cc2012-03-13 13:35:55 +0100215 d = PyFloat_AsDouble(obj);
Victor Stinner3c1b3792014-02-17 00:02:43 +0100216 if (round == _PyTime_ROUND_UP) {
217 if (d >= 0)
218 d = ceil(d);
219 else
220 d = floor(d);
221 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100222 (void)modf(d, &intpart);
223
224 *sec = (time_t)intpart;
225 err = intpart - (double)*sec;
226 if (err <= -1.0 || err >= 1.0) {
227 error_time_t_overflow();
228 return -1;
229 }
230 return 0;
231 }
232 else {
233 *sec = _PyLong_AsTime_t(obj);
234 if (*sec == (time_t)-1 && PyErr_Occurred())
235 return -1;
236 return 0;
237 }
238}
239
240int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100241_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
242 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100243{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100244 return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100245}
246
247int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100248_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
249 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100250{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100251 return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
Victor Stinner643cd682012-03-02 22:54:03 +0100252}
253
Victor Stinnercb29f012015-03-27 13:31:18 +0100254/****************** NEW _PyTime_t API **********************/
255
256static void
257_PyTime_overflow(void)
258{
259 PyErr_SetString(PyExc_OverflowError,
260 "timestamp too large to convert to C _PyTime_t");
261}
262
Victor Stinner02937aa2015-03-28 05:02:39 +0100263int
264_PyTime_RoundTowardsInfinity(int is_neg, _PyTime_round_t round)
265{
266 if (round == _PyTime_ROUND_FLOOR)
267 return 0;
268 return ((round == _PyTime_ROUND_UP) ^ is_neg);
269}
270
Victor Stinner4bfb4602015-03-27 22:27:24 +0100271_PyTime_t
272_PyTime_FromNanoseconds(PY_LONG_LONG ns)
273{
274 _PyTime_t t;
275 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
276 t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
277 return t;
278}
279
Victor Stinnera47b8812015-03-27 18:16:17 +0100280#ifdef HAVE_CLOCK_GETTIME
Victor Stinnercb29f012015-03-27 13:31:18 +0100281static int
282_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
283{
284 _PyTime_t t;
285 t = (_PyTime_t)ts->tv_sec * SEC_TO_NS;
286 if (t / SEC_TO_NS != ts->tv_sec) {
287 _PyTime_overflow();
288 return -1;
289 }
290
291 t += ts->tv_nsec;
292
293 *tp = t;
294 return 0;
295}
Victor Stinnera47b8812015-03-27 18:16:17 +0100296#else
297static int
298_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
299{
300 _PyTime_t t;
301
302 t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
303 if (t / SEC_TO_NS != tv->tv_sec) {
304 _PyTime_overflow();
305 return -1;
306 }
307
308 t += (_PyTime_t)tv->tv_usec * US_TO_NS;
309
310 *tp = t;
311 return 0;
312}
Victor Stinnercb29f012015-03-27 13:31:18 +0100313#endif
314
315int
Victor Stinner992c43f2015-03-27 17:12:45 +0100316_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
Victor Stinnercb29f012015-03-27 13:31:18 +0100317{
318 if (PyFloat_Check(obj)) {
319 double d, err;
320
321 /* convert to a number of nanoseconds */
322 d = PyFloat_AsDouble(obj);
323 d *= 1e9;
324
Victor Stinner02937aa2015-03-28 05:02:39 +0100325 if (_PyTime_RoundTowardsInfinity(d < 0, round))
Victor Stinnercb29f012015-03-27 13:31:18 +0100326 d = ceil(d);
327 else
328 d = floor(d);
329
330 *t = (_PyTime_t)d;
331 err = d - (double)*t;
332 if (fabs(err) >= 1.0) {
333 _PyTime_overflow();
334 return -1;
335 }
336 return 0;
337 }
338 else {
339#ifdef HAVE_LONG_LONG
340 PY_LONG_LONG sec;
341 sec = PyLong_AsLongLong(obj);
342 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
343#else
344 long sec;
345 sec = PyLong_AsLong(obj);
346 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
347#endif
348 if (sec == -1 && PyErr_Occurred()) {
349 if (PyErr_ExceptionMatches(PyExc_OverflowError))
350 _PyTime_overflow();
351 return -1;
352 }
353 *t = sec * SEC_TO_NS;
354 if (*t / SEC_TO_NS != sec) {
355 _PyTime_overflow();
356 return -1;
357 }
358 return 0;
359 }
360}
361
Victor Stinner4bfb4602015-03-27 22:27:24 +0100362double
363_PyTime_AsSecondsDouble(_PyTime_t t)
364{
365 _PyTime_t sec, ns;
366 /* Divide using integers to avoid rounding issues on the integer part.
367 1e-9 cannot be stored exactly in IEEE 64-bit. */
368 sec = t / SEC_TO_NS;
369 ns = t % SEC_TO_NS;
370 return (double)sec + (double)ns * 1e-9;
371}
372
Victor Stinner992c43f2015-03-27 17:12:45 +0100373PyObject *
374_PyTime_AsNanosecondsObject(_PyTime_t t)
375{
376#ifdef HAVE_LONG_LONG
377 assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
378 return PyLong_FromLongLong((PY_LONG_LONG)t);
379#else
380 assert(sizeof(long) >= sizeof(_PyTime_t));
381 return PyLong_FromLong((long)t);
382#endif
383}
384
Victor Stinnercb29f012015-03-27 13:31:18 +0100385static _PyTime_t
386_PyTime_Multiply(_PyTime_t t, unsigned int multiply, _PyTime_round_t round)
387{
388 _PyTime_t k;
389 if (multiply < SEC_TO_NS) {
390 k = SEC_TO_NS / multiply;
Victor Stinner02937aa2015-03-28 05:02:39 +0100391 if (_PyTime_RoundTowardsInfinity(t < 0, round))
Victor Stinnercb29f012015-03-27 13:31:18 +0100392 return (t + k - 1) / k;
393 else
394 return t / k;
395 }
396 else {
397 k = multiply / SEC_TO_NS;
398 return t * k;
399 }
400}
401
402_PyTime_t
403_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
404{
405 return _PyTime_Multiply(t, 1000, round);
406}
407
Victor Stinner02937aa2015-03-28 05:02:39 +0100408/* FIXME: write unit tests */
Victor Stinnerf5faad22015-03-28 03:52:05 +0100409_PyTime_t
410_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
411{
412 return _PyTime_Multiply(t, 1000 * 1000, round);
413}
414
Victor Stinnercb29f012015-03-27 13:31:18 +0100415int
416_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
417{
418 _PyTime_t secs, ns;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100419 int res = 0;
Victor Stinnercb29f012015-03-27 13:31:18 +0100420
421 secs = t / SEC_TO_NS;
422 ns = t % SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100423 if (ns < 0) {
424 ns += SEC_TO_NS;
425 secs -= 1;
426 }
Victor Stinnercb29f012015-03-27 13:31:18 +0100427
428#ifdef MS_WINDOWS
429 /* On Windows, timeval.tv_sec is a long (32 bit),
430 whereas time_t can be 64-bit. */
431 assert(sizeof(tv->tv_sec) == sizeof(long));
432#if SIZEOF_TIME_T > SIZEOF_LONG
433 if (secs > LONG_MAX) {
Victor Stinner95e9cef2015-03-28 01:26:47 +0100434 secs = LONG_MAX;
435 res = -1;
436 }
437 else if (secs < LONG_MIN) {
438 secs = LONG_MIN;
439 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100440 }
441#endif
442 tv->tv_sec = (long)secs;
443#else
444 /* On OpenBSD 5.4, timeval.tv_sec is a long.
445 Example: long is 64-bit, whereas time_t is 32-bit. */
446 tv->tv_sec = secs;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100447 if ((_PyTime_t)tv->tv_sec != secs)
448 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100449#endif
450
Victor Stinner02937aa2015-03-28 05:02:39 +0100451 if (_PyTime_RoundTowardsInfinity(tv->tv_sec < 0, round))
Victor Stinnercb29f012015-03-27 13:31:18 +0100452 tv->tv_usec = (int)((ns + US_TO_NS - 1) / US_TO_NS);
453 else
454 tv->tv_usec = (int)(ns / US_TO_NS);
Victor Stinner95e9cef2015-03-28 01:26:47 +0100455
456 if (tv->tv_usec >= SEC_TO_US) {
457 tv->tv_usec -= SEC_TO_US;
458 tv->tv_sec += 1;
459 }
460
461 return res;
Victor Stinnercb29f012015-03-27 13:31:18 +0100462}
463
Victor Stinnerc3378382015-03-28 05:07:51 +0100464#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
Victor Stinner34dc0f42015-03-27 18:19:03 +0100465int
466_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
467{
Victor Stinner95e9cef2015-03-28 01:26:47 +0100468 _PyTime_t secs, nsec;
469
470 secs = t / SEC_TO_NS;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100471 nsec = t % SEC_TO_NS;
472 if (nsec < 0) {
473 nsec += SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100474 secs -= 1;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100475 }
Victor Stinner95e9cef2015-03-28 01:26:47 +0100476 ts->tv_sec = (time_t)secs;
477 if ((_PyTime_t)ts->tv_sec != secs) {
Victor Stinner34dc0f42015-03-27 18:19:03 +0100478 _PyTime_overflow();
479 return -1;
480 }
481 ts->tv_nsec = nsec;
482 return 0;
483}
484#endif
485
Victor Stinnercb29f012015-03-27 13:31:18 +0100486static int
Victor Stinnera47b8812015-03-27 18:16:17 +0100487pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
488{
489#ifdef MS_WINDOWS
490 FILETIME system_time;
491 ULARGE_INTEGER large;
492
493 assert(info == NULL || raise);
494
495 GetSystemTimeAsFileTime(&system_time);
496 large.u.LowPart = system_time.dwLowDateTime;
497 large.u.HighPart = system_time.dwHighDateTime;
498 /* 11,644,473,600,000,000,000: number of nanoseconds between
499 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
500 days). */
501 *tp = large.QuadPart * 100 - 11644473600000000000;
502 if (info) {
503 DWORD timeAdjustment, timeIncrement;
504 BOOL isTimeAdjustmentDisabled, ok;
505
506 info->implementation = "GetSystemTimeAsFileTime()";
507 info->monotonic = 0;
508 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
509 &isTimeAdjustmentDisabled);
510 if (!ok) {
511 PyErr_SetFromWindowsErr(0);
512 return -1;
513 }
514 info->resolution = timeIncrement * 1e-7;
515 info->adjustable = 1;
516 }
517
518#else /* MS_WINDOWS */
519 int err;
520#ifdef HAVE_CLOCK_GETTIME
521 struct timespec ts;
522#else
523 struct timeval tv;
524#endif
525
526 assert(info == NULL || raise);
527
528#ifdef HAVE_CLOCK_GETTIME
529 err = clock_gettime(CLOCK_REALTIME, &ts);
530 if (err) {
531 if (raise)
532 PyErr_SetFromErrno(PyExc_OSError);
533 return -1;
534 }
535 if (_PyTime_FromTimespec(tp, &ts) < 0)
536 return -1;
537
538 if (info) {
539 struct timespec res;
540 info->implementation = "clock_gettime(CLOCK_REALTIME)";
541 info->monotonic = 0;
542 info->adjustable = 1;
543 if (clock_getres(CLOCK_REALTIME, &res) == 0)
544 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
545 else
546 info->resolution = 1e-9;
547 }
548#else /* HAVE_CLOCK_GETTIME */
549
550 /* test gettimeofday() */
551#ifdef GETTIMEOFDAY_NO_TZ
552 err = gettimeofday(&tv);
553#else
554 err = gettimeofday(&tv, (struct timezone *)NULL);
555#endif
556 if (err) {
557 if (raise)
558 PyErr_SetFromErrno(PyExc_OSError);
559 return -1;
560 }
561 if (_PyTime_FromTimeval(tp, &tv) < 0)
562 return -1;
563
564 if (info) {
565 info->implementation = "gettimeofday()";
566 info->resolution = 1e-6;
567 info->monotonic = 0;
568 info->adjustable = 1;
569 }
570#endif /* !HAVE_CLOCK_GETTIME */
571#endif /* !MS_WINDOWS */
572 return 0;
573}
574
575int
576_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
577{
578 return pygettimeofday_new(t, info, 1);
579}
580
581
582static int
Victor Stinnercb29f012015-03-27 13:31:18 +0100583pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
584{
585#ifdef Py_DEBUG
586 static int last_set = 0;
587 static _PyTime_t last = 0;
588#endif
589#if defined(MS_WINDOWS)
Victor Stinnercb29f012015-03-27 13:31:18 +0100590 ULONGLONG result;
591
592 assert(info == NULL || raise);
593
Victor Stinnereb352292015-03-27 14:12:08 +0100594 result = GetTickCount64();
Victor Stinnercb29f012015-03-27 13:31:18 +0100595
596 *tp = result * MS_TO_NS;
597 if (*tp / MS_TO_NS != result) {
598 if (raise) {
599 _PyTime_overflow();
600 return -1;
601 }
602 /* Hello, time traveler! */
603 assert(0);
604 }
605
606 if (info) {
607 DWORD timeAdjustment, timeIncrement;
608 BOOL isTimeAdjustmentDisabled, ok;
Victor Stinnereb352292015-03-27 14:12:08 +0100609 info->implementation = "GetTickCount64()";
Victor Stinnercb29f012015-03-27 13:31:18 +0100610 info->monotonic = 1;
611 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
612 &isTimeAdjustmentDisabled);
613 if (!ok) {
614 PyErr_SetFromWindowsErr(0);
615 return -1;
616 }
617 info->resolution = timeIncrement * 1e-7;
618 info->adjustable = 0;
619 }
620
621#elif defined(__APPLE__)
622 static mach_timebase_info_data_t timebase;
623 uint64_t time;
624
625 if (timebase.denom == 0) {
626 /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
627 fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
628 (void)mach_timebase_info(&timebase);
629 }
630
631 time = mach_absolute_time();
632
633 /* apply timebase factor */
634 time *= timebase.numer;
635 time /= timebase.denom;
636
637 *tp = time;
638
639 if (info) {
640 info->implementation = "mach_absolute_time()";
641 info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
642 info->monotonic = 1;
643 info->adjustable = 0;
644 }
645
646#else
647 struct timespec ts;
648#ifdef CLOCK_HIGHRES
649 const clockid_t clk_id = CLOCK_HIGHRES;
650 const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
651#else
652 const clockid_t clk_id = CLOCK_MONOTONIC;
653 const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
654#endif
655
656 assert(info == NULL || raise);
657
658 if (clock_gettime(clk_id, &ts) != 0) {
659 if (raise) {
660 PyErr_SetFromErrno(PyExc_OSError);
661 return -1;
662 }
663 return -1;
664 }
665
666 if (info) {
667 struct timespec res;
668 info->monotonic = 1;
669 info->implementation = implementation;
670 info->adjustable = 0;
671 if (clock_getres(clk_id, &res) != 0) {
672 PyErr_SetFromErrno(PyExc_OSError);
673 return -1;
674 }
675 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
676 }
677 if (_PyTime_FromTimespec(tp, &ts) < 0)
678 return -1;
679#endif
680#ifdef Py_DEBUG
681 /* monotonic clock cannot go backward */
682 assert(!last_set || last <= *tp);
683 last = *tp;
684 last_set = 1;
685#endif
686 return 0;
687}
688
689_PyTime_t
690_PyTime_GetMonotonicClock(void)
691{
692 _PyTime_t t;
693 if (pymonotonic_new(&t, NULL, 0) < 0) {
694 /* cannot happen, _PyTime_Init() checks that pymonotonic_new() works */
695 assert(0);
696 t = 0;
697 }
698 return t;
699}
700
Victor Stinner00111242014-08-29 16:31:59 +0200701int
Victor Stinner4bfb4602015-03-27 22:27:24 +0100702_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
703{
704 return pymonotonic_new(tp, info, 1);
705}
706
707int
Victor Stinner00111242014-08-29 16:31:59 +0200708_PyTime_Init(void)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000709{
Victor Stinner00111242014-08-29 16:31:59 +0200710 _PyTime_timeval tv;
Victor Stinnercb29f012015-03-27 13:31:18 +0100711 _PyTime_t t;
712
Victor Stinner00111242014-08-29 16:31:59 +0200713 /* ensure that the system clock works */
Victor Stinnera47b8812015-03-27 18:16:17 +0100714 if (pygettimeofday(&tv, NULL, 1) < 0)
715 return -1;
716
717 /* ensure that the system clock works */
718 if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
Victor Stinner00111242014-08-29 16:31:59 +0200719 return -1;
Victor Stinnerae586492014-09-02 23:18:25 +0200720
721 /* ensure that the operating system provides a monotonic clock */
Victor Stinnera47b8812015-03-27 18:16:17 +0100722 if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
Victor Stinnercb29f012015-03-27 13:31:18 +0100723 return -1;
Victor Stinner00111242014-08-29 16:31:59 +0200724 return 0;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000725}