blob: 003003bdcab41b084a45591d0588f9cc0dacd779 [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 Stinner5d272cc2012-03-13 13:35:55 +010022static void
23error_time_t_overflow(void)
Victor Stinner643cd682012-03-02 22:54:03 +010024{
Victor Stinner5d272cc2012-03-13 13:35:55 +010025 PyErr_SetString(PyExc_OverflowError,
26 "timestamp out of range for platform time_t");
27}
28
Larry Hastings76ad59b2012-05-03 00:30:07 -070029time_t
Victor Stinner5d272cc2012-03-13 13:35:55 +010030_PyLong_AsTime_t(PyObject *obj)
31{
32#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
33 PY_LONG_LONG val;
34 val = PyLong_AsLongLong(obj);
35#else
36 long val;
37 assert(sizeof(time_t) <= sizeof(long));
38 val = PyLong_AsLong(obj);
39#endif
40 if (val == -1 && PyErr_Occurred()) {
41 if (PyErr_ExceptionMatches(PyExc_OverflowError))
42 error_time_t_overflow();
43 return -1;
44 }
45 return (time_t)val;
46}
47
Larry Hastings6fe20b32012-04-19 15:07:49 -070048PyObject *
49_PyLong_FromTime_t(time_t t)
50{
51#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
52 return PyLong_FromLongLong((PY_LONG_LONG)t);
53#else
54 assert(sizeof(time_t) <= sizeof(long));
55 return PyLong_FromLong((long)t);
56#endif
57}
58
Victor Stinner5d272cc2012-03-13 13:35:55 +010059static int
60_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
Victor Stinner3c1b3792014-02-17 00:02:43 +010061 double denominator, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +010062{
63 assert(denominator <= LONG_MAX);
Victor Stinner643cd682012-03-02 22:54:03 +010064 if (PyFloat_Check(obj)) {
Victor Stinnerbd273c12012-03-13 19:12:23 +010065 double d, intpart, err;
66 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
67 volatile double floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +010068
69 d = PyFloat_AsDouble(obj);
70 floatpart = modf(d, &intpart);
71 if (floatpart < 0) {
72 floatpart = 1.0 + floatpart;
73 intpart -= 1.0;
74 }
75
Victor Stinner3c1b3792014-02-17 00:02:43 +010076 floatpart *= denominator;
Victor Stinnera695f832015-03-30 03:57:14 +020077 if (round == _PyTime_ROUND_CEILING) {
Victor Stinnerf81f0f92015-03-30 00:44:06 +020078 floatpart = ceil(floatpart);
79 if (floatpart >= denominator) {
80 floatpart = 0.0;
81 intpart += 1.0;
Victor Stinner3c1b3792014-02-17 00:02:43 +010082 }
Victor Stinnerf81f0f92015-03-30 00:44:06 +020083 }
84 else {
85 floatpart = floor(floatpart);
Victor Stinner3c1b3792014-02-17 00:02:43 +010086 }
87
Victor Stinner643cd682012-03-02 22:54:03 +010088 *sec = (time_t)intpart;
89 err = intpart - (double)*sec;
Victor Stinner5d272cc2012-03-13 13:35:55 +010090 if (err <= -1.0 || err >= 1.0) {
91 error_time_t_overflow();
92 return -1;
93 }
Victor Stinner643cd682012-03-02 22:54:03 +010094
Victor Stinner5d272cc2012-03-13 13:35:55 +010095 *numerator = (long)floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +010096 return 0;
97 }
98 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +010099 *sec = _PyLong_AsTime_t(obj);
100 if (*sec == (time_t)-1 && PyErr_Occurred())
101 return -1;
102 *numerator = 0;
Victor Stinner643cd682012-03-02 22:54:03 +0100103 return 0;
104 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100105}
Victor Stinner643cd682012-03-02 22:54:03 +0100106
Victor Stinner5d272cc2012-03-13 13:35:55 +0100107int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100108_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100109{
110 if (PyFloat_Check(obj)) {
111 double d, intpart, err;
112
Victor Stinner5d272cc2012-03-13 13:35:55 +0100113 d = PyFloat_AsDouble(obj);
Victor Stinnera695f832015-03-30 03:57:14 +0200114 if (round == _PyTime_ROUND_CEILING)
Victor Stinnerf81f0f92015-03-30 00:44:06 +0200115 d = ceil(d);
116 else
117 d = floor(d);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100118 (void)modf(d, &intpart);
119
120 *sec = (time_t)intpart;
121 err = intpart - (double)*sec;
122 if (err <= -1.0 || err >= 1.0) {
123 error_time_t_overflow();
124 return -1;
125 }
126 return 0;
127 }
128 else {
129 *sec = _PyLong_AsTime_t(obj);
130 if (*sec == (time_t)-1 && PyErr_Occurred())
131 return -1;
132 return 0;
133 }
134}
135
136int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100137_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
138 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100139{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100140 return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100141}
142
143int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100144_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
145 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100146{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100147 return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
Victor Stinner643cd682012-03-02 22:54:03 +0100148}
149
Victor Stinnercb29f012015-03-27 13:31:18 +0100150static void
151_PyTime_overflow(void)
152{
153 PyErr_SetString(PyExc_OverflowError,
154 "timestamp too large to convert to C _PyTime_t");
155}
156
Victor Stinner4bfb4602015-03-27 22:27:24 +0100157_PyTime_t
158_PyTime_FromNanoseconds(PY_LONG_LONG ns)
159{
160 _PyTime_t t;
161 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
162 t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
163 return t;
164}
165
Victor Stinnera47b8812015-03-27 18:16:17 +0100166#ifdef HAVE_CLOCK_GETTIME
Victor Stinnercb29f012015-03-27 13:31:18 +0100167static int
Victor Stinnercb0c6022015-03-28 05:24:19 +0100168_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise)
Victor Stinnercb29f012015-03-27 13:31:18 +0100169{
170 _PyTime_t t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100171 int res = 0;
172
Victor Stinnercb29f012015-03-27 13:31:18 +0100173 t = (_PyTime_t)ts->tv_sec * SEC_TO_NS;
174 if (t / SEC_TO_NS != ts->tv_sec) {
Victor Stinnercb0c6022015-03-28 05:24:19 +0100175 if (raise)
176 _PyTime_overflow();
177 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100178 }
179
180 t += ts->tv_nsec;
181
182 *tp = t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100183 return res;
Victor Stinnercb29f012015-03-27 13:31:18 +0100184}
Victor Stinner1bd18ba2015-03-30 00:25:38 +0200185#elif !defined(MS_WINDOWS)
Victor Stinnera47b8812015-03-27 18:16:17 +0100186static int
Victor Stinnercb0c6022015-03-28 05:24:19 +0100187_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise)
Victor Stinnera47b8812015-03-27 18:16:17 +0100188{
189 _PyTime_t t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100190 int res = 0;
Victor Stinnera47b8812015-03-27 18:16:17 +0100191
192 t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
193 if (t / SEC_TO_NS != tv->tv_sec) {
Victor Stinnercb0c6022015-03-28 05:24:19 +0100194 if (raise)
195 _PyTime_overflow();
196 res = -1;
Victor Stinnera47b8812015-03-27 18:16:17 +0100197 }
198
199 t += (_PyTime_t)tv->tv_usec * US_TO_NS;
200
201 *tp = t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100202 return res;
Victor Stinnera47b8812015-03-27 18:16:17 +0100203}
Victor Stinnercb29f012015-03-27 13:31:18 +0100204#endif
205
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200206static int
207_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
208 long to_nanoseconds)
Victor Stinnercb29f012015-03-27 13:31:18 +0100209{
210 if (PyFloat_Check(obj)) {
Victor Stinner45cff0c2015-03-30 10:22:16 +0200211 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
212 volatile double d, err;
Victor Stinnercb29f012015-03-27 13:31:18 +0100213
214 /* convert to a number of nanoseconds */
215 d = PyFloat_AsDouble(obj);
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200216 d *= to_nanoseconds;
Victor Stinnercb29f012015-03-27 13:31:18 +0100217
Victor Stinnera695f832015-03-30 03:57:14 +0200218 if (round == _PyTime_ROUND_CEILING)
Victor Stinnercb29f012015-03-27 13:31:18 +0100219 d = ceil(d);
220 else
221 d = floor(d);
222
223 *t = (_PyTime_t)d;
224 err = d - (double)*t;
225 if (fabs(err) >= 1.0) {
226 _PyTime_overflow();
227 return -1;
228 }
229 return 0;
230 }
231 else {
232#ifdef HAVE_LONG_LONG
233 PY_LONG_LONG sec;
234 sec = PyLong_AsLongLong(obj);
235 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
236#else
237 long sec;
238 sec = PyLong_AsLong(obj);
239 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
240#endif
241 if (sec == -1 && PyErr_Occurred()) {
242 if (PyErr_ExceptionMatches(PyExc_OverflowError))
243 _PyTime_overflow();
244 return -1;
245 }
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200246 *t = sec * to_nanoseconds;
247 if (*t / to_nanoseconds != sec) {
Victor Stinnercb29f012015-03-27 13:31:18 +0100248 _PyTime_overflow();
249 return -1;
250 }
251 return 0;
252 }
253}
254
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200255int
256_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
257{
258 return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
259}
260
261int
262_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
263{
264 return _PyTime_FromObject(t, obj, round, MS_TO_NS);
265}
266
Victor Stinner4bfb4602015-03-27 22:27:24 +0100267double
268_PyTime_AsSecondsDouble(_PyTime_t t)
269{
270 _PyTime_t sec, ns;
271 /* Divide using integers to avoid rounding issues on the integer part.
272 1e-9 cannot be stored exactly in IEEE 64-bit. */
273 sec = t / SEC_TO_NS;
274 ns = t % SEC_TO_NS;
275 return (double)sec + (double)ns * 1e-9;
276}
277
Victor Stinner992c43f2015-03-27 17:12:45 +0100278PyObject *
279_PyTime_AsNanosecondsObject(_PyTime_t t)
280{
281#ifdef HAVE_LONG_LONG
282 assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
283 return PyLong_FromLongLong((PY_LONG_LONG)t);
284#else
285 assert(sizeof(long) >= sizeof(_PyTime_t));
286 return PyLong_FromLong((long)t);
287#endif
288}
289
Victor Stinnercb29f012015-03-27 13:31:18 +0100290static _PyTime_t
291_PyTime_Multiply(_PyTime_t t, unsigned int multiply, _PyTime_round_t round)
292{
293 _PyTime_t k;
294 if (multiply < SEC_TO_NS) {
295 k = SEC_TO_NS / multiply;
Victor Stinnera695f832015-03-30 03:57:14 +0200296 if (round == _PyTime_ROUND_CEILING)
Victor Stinnercb29f012015-03-27 13:31:18 +0100297 return (t + k - 1) / k;
298 else
299 return t / k;
300 }
301 else {
302 k = multiply / SEC_TO_NS;
303 return t * k;
304 }
305}
306
307_PyTime_t
308_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
309{
310 return _PyTime_Multiply(t, 1000, round);
311}
312
Victor Stinner02937aa2015-03-28 05:02:39 +0100313/* FIXME: write unit tests */
Victor Stinnerf5faad22015-03-28 03:52:05 +0100314_PyTime_t
315_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
316{
317 return _PyTime_Multiply(t, 1000 * 1000, round);
318}
319
Victor Stinnerea9c0dd2015-03-30 02:51:13 +0200320static int
321_PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
322 int raise)
Victor Stinnercb29f012015-03-27 13:31:18 +0100323{
324 _PyTime_t secs, ns;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100325 int res = 0;
Victor Stinnercb29f012015-03-27 13:31:18 +0100326
327 secs = t / SEC_TO_NS;
328 ns = t % SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100329 if (ns < 0) {
330 ns += SEC_TO_NS;
331 secs -= 1;
332 }
Victor Stinnercb29f012015-03-27 13:31:18 +0100333
334#ifdef MS_WINDOWS
335 /* On Windows, timeval.tv_sec is a long (32 bit),
336 whereas time_t can be 64-bit. */
337 assert(sizeof(tv->tv_sec) == sizeof(long));
338#if SIZEOF_TIME_T > SIZEOF_LONG
339 if (secs > LONG_MAX) {
Victor Stinner95e9cef2015-03-28 01:26:47 +0100340 secs = LONG_MAX;
341 res = -1;
342 }
343 else if (secs < LONG_MIN) {
344 secs = LONG_MIN;
345 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100346 }
347#endif
348 tv->tv_sec = (long)secs;
349#else
350 /* On OpenBSD 5.4, timeval.tv_sec is a long.
351 Example: long is 64-bit, whereas time_t is 32-bit. */
352 tv->tv_sec = secs;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100353 if ((_PyTime_t)tv->tv_sec != secs)
354 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100355#endif
356
Victor Stinnera695f832015-03-30 03:57:14 +0200357 if (round == _PyTime_ROUND_CEILING)
Victor Stinnercb29f012015-03-27 13:31:18 +0100358 tv->tv_usec = (int)((ns + US_TO_NS - 1) / US_TO_NS);
359 else
360 tv->tv_usec = (int)(ns / US_TO_NS);
Victor Stinner95e9cef2015-03-28 01:26:47 +0100361
362 if (tv->tv_usec >= SEC_TO_US) {
363 tv->tv_usec -= SEC_TO_US;
364 tv->tv_sec += 1;
365 }
366
Victor Stinnerea9c0dd2015-03-30 02:51:13 +0200367 if (res && raise)
368 _PyTime_overflow();
Victor Stinneredddf992015-03-30 02:54:57 +0200369
370 assert(0 <= tv->tv_usec && tv->tv_usec <= 999999);
Victor Stinner95e9cef2015-03-28 01:26:47 +0100371 return res;
Victor Stinnercb29f012015-03-27 13:31:18 +0100372}
373
Victor Stinnerea9c0dd2015-03-30 02:51:13 +0200374int
375_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
376{
377 return _PyTime_AsTimeval_impl(t, tv, round, 1);
378}
379
380int
381_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
382{
383 return _PyTime_AsTimeval_impl(t, tv, round, 0);
384}
385
Victor Stinnerc3378382015-03-28 05:07:51 +0100386#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
Victor Stinner34dc0f42015-03-27 18:19:03 +0100387int
388_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
389{
Victor Stinner95e9cef2015-03-28 01:26:47 +0100390 _PyTime_t secs, nsec;
391
392 secs = t / SEC_TO_NS;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100393 nsec = t % SEC_TO_NS;
394 if (nsec < 0) {
395 nsec += SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100396 secs -= 1;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100397 }
Victor Stinner95e9cef2015-03-28 01:26:47 +0100398 ts->tv_sec = (time_t)secs;
399 if ((_PyTime_t)ts->tv_sec != secs) {
Victor Stinner34dc0f42015-03-27 18:19:03 +0100400 _PyTime_overflow();
401 return -1;
402 }
403 ts->tv_nsec = nsec;
Victor Stinneredddf992015-03-30 02:54:57 +0200404
405 assert(0 <= ts->tv_nsec && ts->tv_nsec <= 999999999);
Victor Stinner34dc0f42015-03-27 18:19:03 +0100406 return 0;
407}
408#endif
409
Victor Stinnercb29f012015-03-27 13:31:18 +0100410static int
Victor Stinnera47b8812015-03-27 18:16:17 +0100411pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
412{
413#ifdef MS_WINDOWS
414 FILETIME system_time;
415 ULARGE_INTEGER large;
416
417 assert(info == NULL || raise);
418
419 GetSystemTimeAsFileTime(&system_time);
420 large.u.LowPart = system_time.dwLowDateTime;
421 large.u.HighPart = system_time.dwHighDateTime;
422 /* 11,644,473,600,000,000,000: number of nanoseconds between
423 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
424 days). */
425 *tp = large.QuadPart * 100 - 11644473600000000000;
426 if (info) {
427 DWORD timeAdjustment, timeIncrement;
428 BOOL isTimeAdjustmentDisabled, ok;
429
430 info->implementation = "GetSystemTimeAsFileTime()";
431 info->monotonic = 0;
432 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
433 &isTimeAdjustmentDisabled);
434 if (!ok) {
435 PyErr_SetFromWindowsErr(0);
436 return -1;
437 }
438 info->resolution = timeIncrement * 1e-7;
439 info->adjustable = 1;
440 }
441
442#else /* MS_WINDOWS */
443 int err;
444#ifdef HAVE_CLOCK_GETTIME
445 struct timespec ts;
446#else
447 struct timeval tv;
448#endif
449
450 assert(info == NULL || raise);
451
452#ifdef HAVE_CLOCK_GETTIME
453 err = clock_gettime(CLOCK_REALTIME, &ts);
454 if (err) {
455 if (raise)
456 PyErr_SetFromErrno(PyExc_OSError);
457 return -1;
458 }
Victor Stinnercb0c6022015-03-28 05:24:19 +0100459 if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
Victor Stinnera47b8812015-03-27 18:16:17 +0100460 return -1;
461
462 if (info) {
463 struct timespec res;
464 info->implementation = "clock_gettime(CLOCK_REALTIME)";
465 info->monotonic = 0;
466 info->adjustable = 1;
467 if (clock_getres(CLOCK_REALTIME, &res) == 0)
468 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
469 else
470 info->resolution = 1e-9;
471 }
472#else /* HAVE_CLOCK_GETTIME */
473
474 /* test gettimeofday() */
475#ifdef GETTIMEOFDAY_NO_TZ
476 err = gettimeofday(&tv);
477#else
478 err = gettimeofday(&tv, (struct timezone *)NULL);
479#endif
480 if (err) {
481 if (raise)
482 PyErr_SetFromErrno(PyExc_OSError);
483 return -1;
484 }
Victor Stinnercb0c6022015-03-28 05:24:19 +0100485 if (_PyTime_FromTimeval(tp, &tv, raise) < 0)
Victor Stinnera47b8812015-03-27 18:16:17 +0100486 return -1;
487
488 if (info) {
489 info->implementation = "gettimeofday()";
490 info->resolution = 1e-6;
491 info->monotonic = 0;
492 info->adjustable = 1;
493 }
494#endif /* !HAVE_CLOCK_GETTIME */
495#endif /* !MS_WINDOWS */
496 return 0;
497}
498
Victor Stinner09e5cf22015-03-30 00:09:18 +0200499_PyTime_t
500_PyTime_GetSystemClock(void)
501{
502 _PyTime_t t;
503 if (pygettimeofday_new(&t, NULL, 0) < 0) {
504 /* should not happen, _PyTime_Init() checked the clock at startup */
505 assert(0);
506
507 /* use a fixed value instead of a random value from the stack */
508 t = 0;
509 }
510 return t;
511}
512
Victor Stinnera47b8812015-03-27 18:16:17 +0100513int
514_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
515{
516 return pygettimeofday_new(t, info, 1);
517}
518
519
520static int
Victor Stinnercb29f012015-03-27 13:31:18 +0100521pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
522{
523#ifdef Py_DEBUG
524 static int last_set = 0;
525 static _PyTime_t last = 0;
526#endif
527#if defined(MS_WINDOWS)
Victor Stinnercb29f012015-03-27 13:31:18 +0100528 ULONGLONG result;
529
530 assert(info == NULL || raise);
531
Victor Stinnereb352292015-03-27 14:12:08 +0100532 result = GetTickCount64();
Victor Stinnercb29f012015-03-27 13:31:18 +0100533
534 *tp = result * MS_TO_NS;
535 if (*tp / MS_TO_NS != result) {
536 if (raise) {
537 _PyTime_overflow();
538 return -1;
539 }
540 /* Hello, time traveler! */
541 assert(0);
542 }
543
544 if (info) {
545 DWORD timeAdjustment, timeIncrement;
546 BOOL isTimeAdjustmentDisabled, ok;
Victor Stinnereb352292015-03-27 14:12:08 +0100547 info->implementation = "GetTickCount64()";
Victor Stinnercb29f012015-03-27 13:31:18 +0100548 info->monotonic = 1;
549 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
550 &isTimeAdjustmentDisabled);
551 if (!ok) {
552 PyErr_SetFromWindowsErr(0);
553 return -1;
554 }
555 info->resolution = timeIncrement * 1e-7;
556 info->adjustable = 0;
557 }
558
559#elif defined(__APPLE__)
560 static mach_timebase_info_data_t timebase;
561 uint64_t time;
562
563 if (timebase.denom == 0) {
564 /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
565 fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
566 (void)mach_timebase_info(&timebase);
567 }
568
569 time = mach_absolute_time();
570
571 /* apply timebase factor */
572 time *= timebase.numer;
573 time /= timebase.denom;
574
575 *tp = time;
576
577 if (info) {
578 info->implementation = "mach_absolute_time()";
579 info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
580 info->monotonic = 1;
581 info->adjustable = 0;
582 }
583
584#else
585 struct timespec ts;
586#ifdef CLOCK_HIGHRES
587 const clockid_t clk_id = CLOCK_HIGHRES;
588 const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
589#else
590 const clockid_t clk_id = CLOCK_MONOTONIC;
591 const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
592#endif
593
594 assert(info == NULL || raise);
595
596 if (clock_gettime(clk_id, &ts) != 0) {
597 if (raise) {
598 PyErr_SetFromErrno(PyExc_OSError);
599 return -1;
600 }
601 return -1;
602 }
603
604 if (info) {
605 struct timespec res;
606 info->monotonic = 1;
607 info->implementation = implementation;
608 info->adjustable = 0;
609 if (clock_getres(clk_id, &res) != 0) {
610 PyErr_SetFromErrno(PyExc_OSError);
611 return -1;
612 }
613 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
614 }
Victor Stinnercb0c6022015-03-28 05:24:19 +0100615 if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
Victor Stinnercb29f012015-03-27 13:31:18 +0100616 return -1;
617#endif
618#ifdef Py_DEBUG
619 /* monotonic clock cannot go backward */
620 assert(!last_set || last <= *tp);
621 last = *tp;
622 last_set = 1;
623#endif
624 return 0;
625}
626
627_PyTime_t
628_PyTime_GetMonotonicClock(void)
629{
630 _PyTime_t t;
631 if (pymonotonic_new(&t, NULL, 0) < 0) {
Victor Stinnercb0c6022015-03-28 05:24:19 +0100632 /* should not happen, _PyTime_Init() checked that monotonic clock at
633 startup */
Victor Stinnercb29f012015-03-27 13:31:18 +0100634 assert(0);
Victor Stinnercb0c6022015-03-28 05:24:19 +0100635
636 /* use a fixed value instead of a random value from the stack */
Victor Stinnercb29f012015-03-27 13:31:18 +0100637 t = 0;
638 }
639 return t;
640}
641
Victor Stinner00111242014-08-29 16:31:59 +0200642int
Victor Stinner4bfb4602015-03-27 22:27:24 +0100643_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
644{
645 return pymonotonic_new(tp, info, 1);
646}
647
648int
Victor Stinner00111242014-08-29 16:31:59 +0200649_PyTime_Init(void)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000650{
Victor Stinnercb29f012015-03-27 13:31:18 +0100651 _PyTime_t t;
652
Victor Stinner00111242014-08-29 16:31:59 +0200653 /* ensure that the system clock works */
Victor Stinnera47b8812015-03-27 18:16:17 +0100654 if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
Victor Stinner00111242014-08-29 16:31:59 +0200655 return -1;
Victor Stinnerae586492014-09-02 23:18:25 +0200656
657 /* ensure that the operating system provides a monotonic clock */
Victor Stinnera47b8812015-03-27 18:16:17 +0100658 if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
Victor Stinnercb29f012015-03-27 13:31:18 +0100659 return -1;
Victor Stinner00111242014-08-29 16:31:59 +0200660 return 0;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000661}