blob: 0f05db424ddd5babc7f521fb2cc643f6169d4763 [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 Stinner4bfb4602015-03-27 22:27:24 +0100263_PyTime_t
264_PyTime_FromNanoseconds(PY_LONG_LONG ns)
265{
266 _PyTime_t t;
267 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
268 t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
269 return t;
270}
271
Victor Stinnera47b8812015-03-27 18:16:17 +0100272#ifdef HAVE_CLOCK_GETTIME
Victor Stinnercb29f012015-03-27 13:31:18 +0100273static int
274_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
275{
276 _PyTime_t t;
277 t = (_PyTime_t)ts->tv_sec * SEC_TO_NS;
278 if (t / SEC_TO_NS != ts->tv_sec) {
279 _PyTime_overflow();
280 return -1;
281 }
282
283 t += ts->tv_nsec;
284
285 *tp = t;
286 return 0;
287}
Victor Stinnera47b8812015-03-27 18:16:17 +0100288#else
289static int
290_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
291{
292 _PyTime_t t;
293
294 t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
295 if (t / SEC_TO_NS != tv->tv_sec) {
296 _PyTime_overflow();
297 return -1;
298 }
299
300 t += (_PyTime_t)tv->tv_usec * US_TO_NS;
301
302 *tp = t;
303 return 0;
304}
Victor Stinnercb29f012015-03-27 13:31:18 +0100305#endif
306
307int
Victor Stinner992c43f2015-03-27 17:12:45 +0100308_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
Victor Stinnercb29f012015-03-27 13:31:18 +0100309{
310 if (PyFloat_Check(obj)) {
311 double d, err;
312
313 /* convert to a number of nanoseconds */
314 d = PyFloat_AsDouble(obj);
315 d *= 1e9;
316
Victor Stinner992c43f2015-03-27 17:12:45 +0100317 if ((round == _PyTime_ROUND_UP) ^ (d < 0))
Victor Stinnercb29f012015-03-27 13:31:18 +0100318 d = ceil(d);
319 else
320 d = floor(d);
321
322 *t = (_PyTime_t)d;
323 err = d - (double)*t;
324 if (fabs(err) >= 1.0) {
325 _PyTime_overflow();
326 return -1;
327 }
328 return 0;
329 }
330 else {
331#ifdef HAVE_LONG_LONG
332 PY_LONG_LONG sec;
333 sec = PyLong_AsLongLong(obj);
334 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
335#else
336 long sec;
337 sec = PyLong_AsLong(obj);
338 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
339#endif
340 if (sec == -1 && PyErr_Occurred()) {
341 if (PyErr_ExceptionMatches(PyExc_OverflowError))
342 _PyTime_overflow();
343 return -1;
344 }
345 *t = sec * SEC_TO_NS;
346 if (*t / SEC_TO_NS != sec) {
347 _PyTime_overflow();
348 return -1;
349 }
350 return 0;
351 }
352}
353
Victor Stinner4bfb4602015-03-27 22:27:24 +0100354double
355_PyTime_AsSecondsDouble(_PyTime_t t)
356{
357 _PyTime_t sec, ns;
358 /* Divide using integers to avoid rounding issues on the integer part.
359 1e-9 cannot be stored exactly in IEEE 64-bit. */
360 sec = t / SEC_TO_NS;
361 ns = t % SEC_TO_NS;
362 return (double)sec + (double)ns * 1e-9;
363}
364
Victor Stinner992c43f2015-03-27 17:12:45 +0100365PyObject *
366_PyTime_AsNanosecondsObject(_PyTime_t t)
367{
368#ifdef HAVE_LONG_LONG
369 assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
370 return PyLong_FromLongLong((PY_LONG_LONG)t);
371#else
372 assert(sizeof(long) >= sizeof(_PyTime_t));
373 return PyLong_FromLong((long)t);
374#endif
375}
376
Victor Stinnercb29f012015-03-27 13:31:18 +0100377static _PyTime_t
378_PyTime_Multiply(_PyTime_t t, unsigned int multiply, _PyTime_round_t round)
379{
380 _PyTime_t k;
381 if (multiply < SEC_TO_NS) {
382 k = SEC_TO_NS / multiply;
383 if (round == _PyTime_ROUND_UP)
384 return (t + k - 1) / k;
385 else
386 return t / k;
387 }
388 else {
389 k = multiply / SEC_TO_NS;
390 return t * k;
391 }
392}
393
394_PyTime_t
395_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
396{
397 return _PyTime_Multiply(t, 1000, round);
398}
399
Victor Stinnerf5faad22015-03-28 03:52:05 +0100400_PyTime_t
401_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
402{
403 return _PyTime_Multiply(t, 1000 * 1000, round);
404}
405
Victor Stinnercb29f012015-03-27 13:31:18 +0100406int
407_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
408{
409 _PyTime_t secs, ns;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100410 int res = 0;
Victor Stinnercb29f012015-03-27 13:31:18 +0100411
412 secs = t / SEC_TO_NS;
413 ns = t % SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100414 if (ns < 0) {
415 ns += SEC_TO_NS;
416 secs -= 1;
417 }
Victor Stinnercb29f012015-03-27 13:31:18 +0100418
419#ifdef MS_WINDOWS
420 /* On Windows, timeval.tv_sec is a long (32 bit),
421 whereas time_t can be 64-bit. */
422 assert(sizeof(tv->tv_sec) == sizeof(long));
423#if SIZEOF_TIME_T > SIZEOF_LONG
424 if (secs > LONG_MAX) {
Victor Stinner95e9cef2015-03-28 01:26:47 +0100425 secs = LONG_MAX;
426 res = -1;
427 }
428 else if (secs < LONG_MIN) {
429 secs = LONG_MIN;
430 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100431 }
432#endif
433 tv->tv_sec = (long)secs;
434#else
435 /* On OpenBSD 5.4, timeval.tv_sec is a long.
436 Example: long is 64-bit, whereas time_t is 32-bit. */
437 tv->tv_sec = secs;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100438 if ((_PyTime_t)tv->tv_sec != secs)
439 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100440#endif
441
Victor Stinner95e9cef2015-03-28 01:26:47 +0100442 if ((round == _PyTime_ROUND_UP) ^ (tv->tv_sec < 0))
Victor Stinnercb29f012015-03-27 13:31:18 +0100443 tv->tv_usec = (int)((ns + US_TO_NS - 1) / US_TO_NS);
444 else
445 tv->tv_usec = (int)(ns / US_TO_NS);
Victor Stinner95e9cef2015-03-28 01:26:47 +0100446
447 if (tv->tv_usec >= SEC_TO_US) {
448 tv->tv_usec -= SEC_TO_US;
449 tv->tv_sec += 1;
450 }
451
452 return res;
Victor Stinnercb29f012015-03-27 13:31:18 +0100453}
454
Victor Stinnerc3378382015-03-28 05:07:51 +0100455#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
Victor Stinner34dc0f42015-03-27 18:19:03 +0100456int
457_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
458{
Victor Stinner95e9cef2015-03-28 01:26:47 +0100459 _PyTime_t secs, nsec;
460
461 secs = t / SEC_TO_NS;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100462 nsec = t % SEC_TO_NS;
463 if (nsec < 0) {
464 nsec += SEC_TO_NS;
Victor Stinner95e9cef2015-03-28 01:26:47 +0100465 secs -= 1;
Victor Stinner34dc0f42015-03-27 18:19:03 +0100466 }
Victor Stinner95e9cef2015-03-28 01:26:47 +0100467 ts->tv_sec = (time_t)secs;
468 if ((_PyTime_t)ts->tv_sec != secs) {
Victor Stinner34dc0f42015-03-27 18:19:03 +0100469 _PyTime_overflow();
470 return -1;
471 }
472 ts->tv_nsec = nsec;
473 return 0;
474}
475#endif
476
Victor Stinnercb29f012015-03-27 13:31:18 +0100477static int
Victor Stinnera47b8812015-03-27 18:16:17 +0100478pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
479{
480#ifdef MS_WINDOWS
481 FILETIME system_time;
482 ULARGE_INTEGER large;
483
484 assert(info == NULL || raise);
485
486 GetSystemTimeAsFileTime(&system_time);
487 large.u.LowPart = system_time.dwLowDateTime;
488 large.u.HighPart = system_time.dwHighDateTime;
489 /* 11,644,473,600,000,000,000: number of nanoseconds between
490 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
491 days). */
492 *tp = large.QuadPart * 100 - 11644473600000000000;
493 if (info) {
494 DWORD timeAdjustment, timeIncrement;
495 BOOL isTimeAdjustmentDisabled, ok;
496
497 info->implementation = "GetSystemTimeAsFileTime()";
498 info->monotonic = 0;
499 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
500 &isTimeAdjustmentDisabled);
501 if (!ok) {
502 PyErr_SetFromWindowsErr(0);
503 return -1;
504 }
505 info->resolution = timeIncrement * 1e-7;
506 info->adjustable = 1;
507 }
508
509#else /* MS_WINDOWS */
510 int err;
511#ifdef HAVE_CLOCK_GETTIME
512 struct timespec ts;
513#else
514 struct timeval tv;
515#endif
516
517 assert(info == NULL || raise);
518
519#ifdef HAVE_CLOCK_GETTIME
520 err = clock_gettime(CLOCK_REALTIME, &ts);
521 if (err) {
522 if (raise)
523 PyErr_SetFromErrno(PyExc_OSError);
524 return -1;
525 }
526 if (_PyTime_FromTimespec(tp, &ts) < 0)
527 return -1;
528
529 if (info) {
530 struct timespec res;
531 info->implementation = "clock_gettime(CLOCK_REALTIME)";
532 info->monotonic = 0;
533 info->adjustable = 1;
534 if (clock_getres(CLOCK_REALTIME, &res) == 0)
535 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
536 else
537 info->resolution = 1e-9;
538 }
539#else /* HAVE_CLOCK_GETTIME */
540
541 /* test gettimeofday() */
542#ifdef GETTIMEOFDAY_NO_TZ
543 err = gettimeofday(&tv);
544#else
545 err = gettimeofday(&tv, (struct timezone *)NULL);
546#endif
547 if (err) {
548 if (raise)
549 PyErr_SetFromErrno(PyExc_OSError);
550 return -1;
551 }
552 if (_PyTime_FromTimeval(tp, &tv) < 0)
553 return -1;
554
555 if (info) {
556 info->implementation = "gettimeofday()";
557 info->resolution = 1e-6;
558 info->monotonic = 0;
559 info->adjustable = 1;
560 }
561#endif /* !HAVE_CLOCK_GETTIME */
562#endif /* !MS_WINDOWS */
563 return 0;
564}
565
566int
567_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
568{
569 return pygettimeofday_new(t, info, 1);
570}
571
572
573static int
Victor Stinnercb29f012015-03-27 13:31:18 +0100574pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
575{
576#ifdef Py_DEBUG
577 static int last_set = 0;
578 static _PyTime_t last = 0;
579#endif
580#if defined(MS_WINDOWS)
Victor Stinnercb29f012015-03-27 13:31:18 +0100581 ULONGLONG result;
582
583 assert(info == NULL || raise);
584
Victor Stinnereb352292015-03-27 14:12:08 +0100585 result = GetTickCount64();
Victor Stinnercb29f012015-03-27 13:31:18 +0100586
587 *tp = result * MS_TO_NS;
588 if (*tp / MS_TO_NS != result) {
589 if (raise) {
590 _PyTime_overflow();
591 return -1;
592 }
593 /* Hello, time traveler! */
594 assert(0);
595 }
596
597 if (info) {
598 DWORD timeAdjustment, timeIncrement;
599 BOOL isTimeAdjustmentDisabled, ok;
Victor Stinnereb352292015-03-27 14:12:08 +0100600 info->implementation = "GetTickCount64()";
Victor Stinnercb29f012015-03-27 13:31:18 +0100601 info->monotonic = 1;
602 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
603 &isTimeAdjustmentDisabled);
604 if (!ok) {
605 PyErr_SetFromWindowsErr(0);
606 return -1;
607 }
608 info->resolution = timeIncrement * 1e-7;
609 info->adjustable = 0;
610 }
611
612#elif defined(__APPLE__)
613 static mach_timebase_info_data_t timebase;
614 uint64_t time;
615
616 if (timebase.denom == 0) {
617 /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
618 fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
619 (void)mach_timebase_info(&timebase);
620 }
621
622 time = mach_absolute_time();
623
624 /* apply timebase factor */
625 time *= timebase.numer;
626 time /= timebase.denom;
627
628 *tp = time;
629
630 if (info) {
631 info->implementation = "mach_absolute_time()";
632 info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
633 info->monotonic = 1;
634 info->adjustable = 0;
635 }
636
637#else
638 struct timespec ts;
639#ifdef CLOCK_HIGHRES
640 const clockid_t clk_id = CLOCK_HIGHRES;
641 const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
642#else
643 const clockid_t clk_id = CLOCK_MONOTONIC;
644 const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
645#endif
646
647 assert(info == NULL || raise);
648
649 if (clock_gettime(clk_id, &ts) != 0) {
650 if (raise) {
651 PyErr_SetFromErrno(PyExc_OSError);
652 return -1;
653 }
654 return -1;
655 }
656
657 if (info) {
658 struct timespec res;
659 info->monotonic = 1;
660 info->implementation = implementation;
661 info->adjustable = 0;
662 if (clock_getres(clk_id, &res) != 0) {
663 PyErr_SetFromErrno(PyExc_OSError);
664 return -1;
665 }
666 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
667 }
668 if (_PyTime_FromTimespec(tp, &ts) < 0)
669 return -1;
670#endif
671#ifdef Py_DEBUG
672 /* monotonic clock cannot go backward */
673 assert(!last_set || last <= *tp);
674 last = *tp;
675 last_set = 1;
676#endif
677 return 0;
678}
679
680_PyTime_t
681_PyTime_GetMonotonicClock(void)
682{
683 _PyTime_t t;
684 if (pymonotonic_new(&t, NULL, 0) < 0) {
685 /* cannot happen, _PyTime_Init() checks that pymonotonic_new() works */
686 assert(0);
687 t = 0;
688 }
689 return t;
690}
691
Victor Stinner00111242014-08-29 16:31:59 +0200692int
Victor Stinner4bfb4602015-03-27 22:27:24 +0100693_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
694{
695 return pymonotonic_new(tp, info, 1);
696}
697
698int
Victor Stinner00111242014-08-29 16:31:59 +0200699_PyTime_Init(void)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000700{
Victor Stinner00111242014-08-29 16:31:59 +0200701 _PyTime_timeval tv;
Victor Stinnercb29f012015-03-27 13:31:18 +0100702 _PyTime_t t;
703
Victor Stinner00111242014-08-29 16:31:59 +0200704 /* ensure that the system clock works */
Victor Stinnera47b8812015-03-27 18:16:17 +0100705 if (pygettimeofday(&tv, NULL, 1) < 0)
706 return -1;
707
708 /* ensure that the system clock works */
709 if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
Victor Stinner00111242014-08-29 16:31:59 +0200710 return -1;
Victor Stinnerae586492014-09-02 23:18:25 +0200711
712 /* ensure that the operating system provides a monotonic clock */
Victor Stinnera47b8812015-03-27 18:16:17 +0100713 if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
Victor Stinnercb29f012015-03-27 13:31:18 +0100714 return -1;
Victor Stinner00111242014-08-29 16:31:59 +0200715 return 0;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000716}