blob: 6bf7030cbaf67e032e3e4fa94d2e4673c2dcb318 [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 Stinner00111242014-08-29 16:31:59 +0200122int
Victor Stinnerec895392012-04-29 02:41:27 +0200123_PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
124{
Victor Stinner00111242014-08-29 16:31:59 +0200125 return pygettimeofday(tp, info, 1);
Victor Stinnerec895392012-04-29 02:41:27 +0200126}
127
Victor Stinnerae586492014-09-02 23:18:25 +0200128static int
129pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
130{
131#ifdef Py_DEBUG
Victor Stinner5789cfb2014-09-03 09:43:48 +0200132 static _PyTime_timeval last = {0, -1};
Victor Stinnerae586492014-09-02 23:18:25 +0200133#endif
134#if defined(MS_WINDOWS)
Victor Stinnerae586492014-09-02 23:18:25 +0200135 ULONGLONG result;
136
137 assert(info == NULL || raise);
138
Steve Dower3e96f322015-03-02 08:01:10 -0800139 result = GetTickCount64();
Victor Stinnerae586492014-09-02 23:18:25 +0200140
Victor Stinner580ef132015-03-20 01:55:04 +0100141 tp->tv_sec = result / SEC_TO_MS;
142 tp->tv_usec = (result % SEC_TO_MS) * MS_TO_US;
Victor Stinnerae586492014-09-02 23:18:25 +0200143
144 if (info) {
145 DWORD timeAdjustment, timeIncrement;
146 BOOL isTimeAdjustmentDisabled, ok;
Steve Dower3e96f322015-03-02 08:01:10 -0800147 info->implementation = "GetTickCount64()";
Victor Stinnerae586492014-09-02 23:18:25 +0200148 info->monotonic = 1;
149 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
150 &isTimeAdjustmentDisabled);
151 if (!ok) {
152 PyErr_SetFromWindowsErr(0);
153 return -1;
154 }
155 info->resolution = timeIncrement * 1e-7;
156 info->adjustable = 0;
157 }
158
159#elif defined(__APPLE__)
160 static mach_timebase_info_data_t timebase;
161 uint64_t time;
162
163 if (timebase.denom == 0) {
164 /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
165 fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
166 (void)mach_timebase_info(&timebase);
167 }
168
169 time = mach_absolute_time();
170
171 /* nanoseconds => microseconds */
Victor Stinner580ef132015-03-20 01:55:04 +0100172 time /= US_TO_NS;
Victor Stinnerae586492014-09-02 23:18:25 +0200173 /* apply timebase factor */
174 time *= timebase.numer;
175 time /= timebase.denom;
Victor Stinner580ef132015-03-20 01:55:04 +0100176 tp->tv_sec = time / SEC_TO_US;
177 tp->tv_usec = time % SEC_TO_US;
Victor Stinnerae586492014-09-02 23:18:25 +0200178
179 if (info) {
180 info->implementation = "mach_absolute_time()";
181 info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
182 info->monotonic = 1;
183 info->adjustable = 0;
184 }
185
186#else
187 struct timespec ts;
188#ifdef CLOCK_HIGHRES
189 const clockid_t clk_id = CLOCK_HIGHRES;
190 const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
191#else
192 const clockid_t clk_id = CLOCK_MONOTONIC;
193 const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
194#endif
195
196 assert(info == NULL || raise);
197
198 if (clock_gettime(clk_id, &ts) != 0) {
199 if (raise) {
200 PyErr_SetFromErrno(PyExc_OSError);
201 return -1;
202 }
203 tp->tv_sec = 0;
204 tp->tv_usec = 0;
205 return -1;
206 }
207
208 if (info) {
209 struct timespec res;
210 info->monotonic = 1;
211 info->implementation = implementation;
212 info->adjustable = 0;
213 if (clock_getres(clk_id, &res) != 0) {
214 PyErr_SetFromErrno(PyExc_OSError);
215 return -1;
216 }
217 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
218 }
219 tp->tv_sec = ts.tv_sec;
Victor Stinner580ef132015-03-20 01:55:04 +0100220 tp->tv_usec = ts.tv_nsec / US_TO_NS;
Victor Stinnerae586492014-09-02 23:18:25 +0200221#endif
Victor Stinner580ef132015-03-20 01:55:04 +0100222 assert(0 <= tp->tv_usec && tp->tv_usec < SEC_TO_US);
Victor Stinnerae586492014-09-02 23:18:25 +0200223#ifdef Py_DEBUG
224 /* monotonic clock cannot go backward */
Victor Stinner5789cfb2014-09-03 09:43:48 +0200225 assert(last.tv_usec == -1
226 || tp->tv_sec > last.tv_sec
Victor Stinnerae586492014-09-02 23:18:25 +0200227 || (tp->tv_sec == last.tv_sec && tp->tv_usec >= last.tv_usec));
228 last = *tp;
229#endif
230 return 0;
231}
232
233void
234_PyTime_monotonic(_PyTime_timeval *tp)
235{
236 if (pymonotonic(tp, NULL, 0) < 0) {
237 /* cannot happen, _PyTime_Init() checks that pymonotonic() works */
238 assert(0);
239 tp->tv_sec = 0;
240 tp->tv_usec = 0;
241 }
242}
243
244int
245_PyTime_monotonic_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
246{
247 return pymonotonic(tp, info, 1);
248}
249
Victor Stinner5d272cc2012-03-13 13:35:55 +0100250static void
251error_time_t_overflow(void)
Victor Stinner643cd682012-03-02 22:54:03 +0100252{
Victor Stinner5d272cc2012-03-13 13:35:55 +0100253 PyErr_SetString(PyExc_OverflowError,
254 "timestamp out of range for platform time_t");
255}
256
Larry Hastings76ad59b2012-05-03 00:30:07 -0700257time_t
Victor Stinner5d272cc2012-03-13 13:35:55 +0100258_PyLong_AsTime_t(PyObject *obj)
259{
260#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
261 PY_LONG_LONG val;
262 val = PyLong_AsLongLong(obj);
263#else
264 long val;
265 assert(sizeof(time_t) <= sizeof(long));
266 val = PyLong_AsLong(obj);
267#endif
268 if (val == -1 && PyErr_Occurred()) {
269 if (PyErr_ExceptionMatches(PyExc_OverflowError))
270 error_time_t_overflow();
271 return -1;
272 }
273 return (time_t)val;
274}
275
Larry Hastings6fe20b32012-04-19 15:07:49 -0700276PyObject *
277_PyLong_FromTime_t(time_t t)
278{
279#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
280 return PyLong_FromLongLong((PY_LONG_LONG)t);
281#else
282 assert(sizeof(time_t) <= sizeof(long));
283 return PyLong_FromLong((long)t);
284#endif
285}
286
Victor Stinner5d272cc2012-03-13 13:35:55 +0100287static int
288_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
Victor Stinner3c1b3792014-02-17 00:02:43 +0100289 double denominator, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100290{
291 assert(denominator <= LONG_MAX);
Victor Stinner643cd682012-03-02 22:54:03 +0100292 if (PyFloat_Check(obj)) {
Victor Stinnerbd273c12012-03-13 19:12:23 +0100293 double d, intpart, err;
294 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
295 volatile double floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +0100296
297 d = PyFloat_AsDouble(obj);
298 floatpart = modf(d, &intpart);
299 if (floatpart < 0) {
300 floatpart = 1.0 + floatpart;
301 intpart -= 1.0;
302 }
303
Victor Stinner3c1b3792014-02-17 00:02:43 +0100304 floatpart *= denominator;
305 if (round == _PyTime_ROUND_UP) {
306 if (intpart >= 0) {
307 floatpart = ceil(floatpart);
308 if (floatpart >= denominator) {
309 floatpart = 0.0;
310 intpart += 1.0;
311 }
312 }
313 else {
314 floatpart = floor(floatpart);
315 }
316 }
317
Victor Stinner643cd682012-03-02 22:54:03 +0100318 *sec = (time_t)intpart;
319 err = intpart - (double)*sec;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100320 if (err <= -1.0 || err >= 1.0) {
321 error_time_t_overflow();
322 return -1;
323 }
Victor Stinner643cd682012-03-02 22:54:03 +0100324
Victor Stinner5d272cc2012-03-13 13:35:55 +0100325 *numerator = (long)floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +0100326 return 0;
327 }
328 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +0100329 *sec = _PyLong_AsTime_t(obj);
330 if (*sec == (time_t)-1 && PyErr_Occurred())
331 return -1;
332 *numerator = 0;
Victor Stinner643cd682012-03-02 22:54:03 +0100333 return 0;
334 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100335}
Victor Stinner643cd682012-03-02 22:54:03 +0100336
Victor Stinner5d272cc2012-03-13 13:35:55 +0100337int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100338_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100339{
340 if (PyFloat_Check(obj)) {
341 double d, intpart, err;
342
Victor Stinner5d272cc2012-03-13 13:35:55 +0100343 d = PyFloat_AsDouble(obj);
Victor Stinner3c1b3792014-02-17 00:02:43 +0100344 if (round == _PyTime_ROUND_UP) {
345 if (d >= 0)
346 d = ceil(d);
347 else
348 d = floor(d);
349 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100350 (void)modf(d, &intpart);
351
352 *sec = (time_t)intpart;
353 err = intpart - (double)*sec;
354 if (err <= -1.0 || err >= 1.0) {
355 error_time_t_overflow();
356 return -1;
357 }
358 return 0;
359 }
360 else {
361 *sec = _PyLong_AsTime_t(obj);
362 if (*sec == (time_t)-1 && PyErr_Occurred())
363 return -1;
364 return 0;
365 }
366}
367
368int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100369_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
370 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100371{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100372 return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100373}
374
375int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100376_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
377 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100378{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100379 return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
Victor Stinner643cd682012-03-02 22:54:03 +0100380}
381
Victor Stinner9a8089b2015-03-20 01:42:20 +0100382void
383_PyTime_AddDouble(_PyTime_timeval *tv, double interval, _PyTime_round_t round)
384{
385 _PyTime_timeval tv2;
386 double frac;
387
388 frac = fmod(interval, 1.0);
389 interval = floor(interval);
390 tv2.tv_sec = (long)interval;
391 tv2.tv_usec = (long)(frac*1e6);
392
393 tv->tv_sec += tv2.tv_sec;
394 tv->tv_usec += tv2.tv_usec;
Victor Stinner580ef132015-03-20 01:55:04 +0100395 tv->tv_sec += (time_t)(tv->tv_usec / SEC_TO_US);
396 tv->tv_usec %= SEC_TO_US;
Victor Stinner9a8089b2015-03-20 01:42:20 +0100397}
398
Victor Stinnercb29f012015-03-27 13:31:18 +0100399/****************** NEW _PyTime_t API **********************/
400
401static void
402_PyTime_overflow(void)
403{
404 PyErr_SetString(PyExc_OverflowError,
405 "timestamp too large to convert to C _PyTime_t");
406}
407
408#if !defined(MS_WINDOWS) && !defined(__APPLE__)
409static int
410_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
411{
412 _PyTime_t t;
413 t = (_PyTime_t)ts->tv_sec * SEC_TO_NS;
414 if (t / SEC_TO_NS != ts->tv_sec) {
415 _PyTime_overflow();
416 return -1;
417 }
418
419 t += ts->tv_nsec;
420
421 *tp = t;
422 return 0;
423}
424#endif
425
426int
427_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
428{
429 if (PyFloat_Check(obj)) {
430 double d, err;
431
432 /* convert to a number of nanoseconds */
433 d = PyFloat_AsDouble(obj);
434 d *= 1e9;
435
436 /* FIXME: use sign */
437 if (round == _PyTime_ROUND_UP)
438 d = ceil(d);
439 else
440 d = floor(d);
441
442 *t = (_PyTime_t)d;
443 err = d - (double)*t;
444 if (fabs(err) >= 1.0) {
445 _PyTime_overflow();
446 return -1;
447 }
448 return 0;
449 }
450 else {
451#ifdef HAVE_LONG_LONG
452 PY_LONG_LONG sec;
453 sec = PyLong_AsLongLong(obj);
454 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
455#else
456 long sec;
457 sec = PyLong_AsLong(obj);
458 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
459#endif
460 if (sec == -1 && PyErr_Occurred()) {
461 if (PyErr_ExceptionMatches(PyExc_OverflowError))
462 _PyTime_overflow();
463 return -1;
464 }
465 *t = sec * SEC_TO_NS;
466 if (*t / SEC_TO_NS != sec) {
467 _PyTime_overflow();
468 return -1;
469 }
470 return 0;
471 }
472}
473
474static _PyTime_t
475_PyTime_Multiply(_PyTime_t t, unsigned int multiply, _PyTime_round_t round)
476{
477 _PyTime_t k;
478 if (multiply < SEC_TO_NS) {
479 k = SEC_TO_NS / multiply;
480 if (round == _PyTime_ROUND_UP)
481 return (t + k - 1) / k;
482 else
483 return t / k;
484 }
485 else {
486 k = multiply / SEC_TO_NS;
487 return t * k;
488 }
489}
490
491_PyTime_t
492_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
493{
494 return _PyTime_Multiply(t, 1000, round);
495}
496
497int
498_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
499{
500 _PyTime_t secs, ns;
501
502 secs = t / SEC_TO_NS;
503 ns = t % SEC_TO_NS;
504
505#ifdef MS_WINDOWS
506 /* On Windows, timeval.tv_sec is a long (32 bit),
507 whereas time_t can be 64-bit. */
508 assert(sizeof(tv->tv_sec) == sizeof(long));
509#if SIZEOF_TIME_T > SIZEOF_LONG
510 if (secs > LONG_MAX) {
511 _PyTime_overflow();
512 return -1;
513 }
514#endif
515 tv->tv_sec = (long)secs;
516#else
517 /* On OpenBSD 5.4, timeval.tv_sec is a long.
518 Example: long is 64-bit, whereas time_t is 32-bit. */
519 tv->tv_sec = secs;
520 if ((_PyTime_t)tv->tv_sec != secs) {
521 _PyTime_overflow();
522 return -1;
523 }
524#endif
525
526 if (round == _PyTime_ROUND_UP)
527 tv->tv_usec = (int)((ns + US_TO_NS - 1) / US_TO_NS);
528 else
529 tv->tv_usec = (int)(ns / US_TO_NS);
530 return 0;
531}
532
533static int
534pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
535{
536#ifdef Py_DEBUG
537 static int last_set = 0;
538 static _PyTime_t last = 0;
539#endif
540#if defined(MS_WINDOWS)
Victor Stinnercb29f012015-03-27 13:31:18 +0100541 ULONGLONG result;
542
543 assert(info == NULL || raise);
544
Victor Stinnereb352292015-03-27 14:12:08 +0100545 result = GetTickCount64();
Victor Stinnercb29f012015-03-27 13:31:18 +0100546
547 *tp = result * MS_TO_NS;
548 if (*tp / MS_TO_NS != result) {
549 if (raise) {
550 _PyTime_overflow();
551 return -1;
552 }
553 /* Hello, time traveler! */
554 assert(0);
555 }
556
557 if (info) {
558 DWORD timeAdjustment, timeIncrement;
559 BOOL isTimeAdjustmentDisabled, ok;
Victor Stinnereb352292015-03-27 14:12:08 +0100560 info->implementation = "GetTickCount64()";
Victor Stinnercb29f012015-03-27 13:31:18 +0100561 info->monotonic = 1;
562 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
563 &isTimeAdjustmentDisabled);
564 if (!ok) {
565 PyErr_SetFromWindowsErr(0);
566 return -1;
567 }
568 info->resolution = timeIncrement * 1e-7;
569 info->adjustable = 0;
570 }
571
572#elif defined(__APPLE__)
573 static mach_timebase_info_data_t timebase;
574 uint64_t time;
575
576 if (timebase.denom == 0) {
577 /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
578 fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
579 (void)mach_timebase_info(&timebase);
580 }
581
582 time = mach_absolute_time();
583
584 /* apply timebase factor */
585 time *= timebase.numer;
586 time /= timebase.denom;
587
588 *tp = time;
589
590 if (info) {
591 info->implementation = "mach_absolute_time()";
592 info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
593 info->monotonic = 1;
594 info->adjustable = 0;
595 }
596
597#else
598 struct timespec ts;
599#ifdef CLOCK_HIGHRES
600 const clockid_t clk_id = CLOCK_HIGHRES;
601 const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
602#else
603 const clockid_t clk_id = CLOCK_MONOTONIC;
604 const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
605#endif
606
607 assert(info == NULL || raise);
608
609 if (clock_gettime(clk_id, &ts) != 0) {
610 if (raise) {
611 PyErr_SetFromErrno(PyExc_OSError);
612 return -1;
613 }
614 return -1;
615 }
616
617 if (info) {
618 struct timespec res;
619 info->monotonic = 1;
620 info->implementation = implementation;
621 info->adjustable = 0;
622 if (clock_getres(clk_id, &res) != 0) {
623 PyErr_SetFromErrno(PyExc_OSError);
624 return -1;
625 }
626 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
627 }
628 if (_PyTime_FromTimespec(tp, &ts) < 0)
629 return -1;
630#endif
631#ifdef Py_DEBUG
632 /* monotonic clock cannot go backward */
633 assert(!last_set || last <= *tp);
634 last = *tp;
635 last_set = 1;
636#endif
637 return 0;
638}
639
640_PyTime_t
641_PyTime_GetMonotonicClock(void)
642{
643 _PyTime_t t;
644 if (pymonotonic_new(&t, NULL, 0) < 0) {
645 /* cannot happen, _PyTime_Init() checks that pymonotonic_new() works */
646 assert(0);
647 t = 0;
648 }
649 return t;
650}
651
Victor Stinner00111242014-08-29 16:31:59 +0200652int
653_PyTime_Init(void)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000654{
Victor Stinner00111242014-08-29 16:31:59 +0200655 _PyTime_timeval tv;
Victor Stinnercb29f012015-03-27 13:31:18 +0100656 _PyTime_t t;
657
Victor Stinner00111242014-08-29 16:31:59 +0200658 /* ensure that the system clock works */
659 if (_PyTime_gettimeofday_info(&tv, NULL) < 0)
660 return -1;
Victor Stinnerae586492014-09-02 23:18:25 +0200661
662 /* ensure that the operating system provides a monotonic clock */
663 if (_PyTime_monotonic_info(&tv, NULL) < 0)
664 return -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100665
666 /* ensure that the operating system provides a monotonic clock */
667 if (pymonotonic_new(&t, NULL, 1) < 0)
668 return -1;
Victor Stinner00111242014-08-29 16:31:59 +0200669 return 0;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000670}