blob: 491bbea61129c15c2d6ebe939ccc0726df253e3a [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 Stinner62d1c702015-04-01 17:47:07 +020022/* Conversion from nanoseconds */
23#define NS_TO_MS (1000 * 1000)
24#define NS_TO_US (1000)
25
Victor Stinner5d272cc2012-03-13 13:35:55 +010026static void
27error_time_t_overflow(void)
Victor Stinner643cd682012-03-02 22:54:03 +010028{
Victor Stinner5d272cc2012-03-13 13:35:55 +010029 PyErr_SetString(PyExc_OverflowError,
30 "timestamp out of range for platform time_t");
31}
32
Larry Hastings76ad59b2012-05-03 00:30:07 -070033time_t
Victor Stinner5d272cc2012-03-13 13:35:55 +010034_PyLong_AsTime_t(PyObject *obj)
35{
36#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
37 PY_LONG_LONG val;
38 val = PyLong_AsLongLong(obj);
39#else
40 long val;
41 assert(sizeof(time_t) <= sizeof(long));
42 val = PyLong_AsLong(obj);
43#endif
44 if (val == -1 && PyErr_Occurred()) {
45 if (PyErr_ExceptionMatches(PyExc_OverflowError))
46 error_time_t_overflow();
47 return -1;
48 }
49 return (time_t)val;
50}
51
Larry Hastings6fe20b32012-04-19 15:07:49 -070052PyObject *
53_PyLong_FromTime_t(time_t t)
54{
55#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
56 return PyLong_FromLongLong((PY_LONG_LONG)t);
57#else
58 assert(sizeof(time_t) <= sizeof(long));
59 return PyLong_FromLong((long)t);
60#endif
61}
62
Victor Stinner5d272cc2012-03-13 13:35:55 +010063static int
64_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
Victor Stinner3c1b3792014-02-17 00:02:43 +010065 double denominator, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +010066{
67 assert(denominator <= LONG_MAX);
Victor Stinner643cd682012-03-02 22:54:03 +010068 if (PyFloat_Check(obj)) {
Victor Stinnerbd273c12012-03-13 19:12:23 +010069 double d, intpart, err;
70 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
71 volatile double floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +010072
73 d = PyFloat_AsDouble(obj);
74 floatpart = modf(d, &intpart);
75 if (floatpart < 0) {
76 floatpart = 1.0 + floatpart;
77 intpart -= 1.0;
78 }
79
Victor Stinner3c1b3792014-02-17 00:02:43 +010080 floatpart *= denominator;
Victor Stinnera695f832015-03-30 03:57:14 +020081 if (round == _PyTime_ROUND_CEILING) {
Victor Stinnerf81f0f92015-03-30 00:44:06 +020082 floatpart = ceil(floatpart);
83 if (floatpart >= denominator) {
84 floatpart = 0.0;
85 intpart += 1.0;
Victor Stinner3c1b3792014-02-17 00:02:43 +010086 }
Victor Stinnerf81f0f92015-03-30 00:44:06 +020087 }
88 else {
89 floatpart = floor(floatpart);
Victor Stinner3c1b3792014-02-17 00:02:43 +010090 }
91
Victor Stinner643cd682012-03-02 22:54:03 +010092 *sec = (time_t)intpart;
93 err = intpart - (double)*sec;
Victor Stinner5d272cc2012-03-13 13:35:55 +010094 if (err <= -1.0 || err >= 1.0) {
95 error_time_t_overflow();
96 return -1;
97 }
Victor Stinner643cd682012-03-02 22:54:03 +010098
Victor Stinner5d272cc2012-03-13 13:35:55 +010099 *numerator = (long)floatpart;
Victor Stinner643cd682012-03-02 22:54:03 +0100100 return 0;
101 }
102 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +0100103 *sec = _PyLong_AsTime_t(obj);
104 if (*sec == (time_t)-1 && PyErr_Occurred())
105 return -1;
106 *numerator = 0;
Victor Stinner643cd682012-03-02 22:54:03 +0100107 return 0;
108 }
Victor Stinner5d272cc2012-03-13 13:35:55 +0100109}
Victor Stinner643cd682012-03-02 22:54:03 +0100110
Victor Stinner5d272cc2012-03-13 13:35:55 +0100111int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100112_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100113{
114 if (PyFloat_Check(obj)) {
115 double d, intpart, err;
116
Victor Stinner5d272cc2012-03-13 13:35:55 +0100117 d = PyFloat_AsDouble(obj);
Victor Stinnera695f832015-03-30 03:57:14 +0200118 if (round == _PyTime_ROUND_CEILING)
Victor Stinnerf81f0f92015-03-30 00:44:06 +0200119 d = ceil(d);
120 else
121 d = floor(d);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100122 (void)modf(d, &intpart);
123
124 *sec = (time_t)intpart;
125 err = intpart - (double)*sec;
126 if (err <= -1.0 || err >= 1.0) {
127 error_time_t_overflow();
128 return -1;
129 }
130 return 0;
131 }
132 else {
133 *sec = _PyLong_AsTime_t(obj);
134 if (*sec == (time_t)-1 && PyErr_Occurred())
135 return -1;
136 return 0;
137 }
138}
139
140int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100141_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
142 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100143{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100144 return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
Victor Stinner5d272cc2012-03-13 13:35:55 +0100145}
146
147int
Victor Stinner3c1b3792014-02-17 00:02:43 +0100148_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
149 _PyTime_round_t round)
Victor Stinner5d272cc2012-03-13 13:35:55 +0100150{
Victor Stinner3c1b3792014-02-17 00:02:43 +0100151 return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
Victor Stinner643cd682012-03-02 22:54:03 +0100152}
153
Victor Stinnercb29f012015-03-27 13:31:18 +0100154static void
155_PyTime_overflow(void)
156{
157 PyErr_SetString(PyExc_OverflowError,
158 "timestamp too large to convert to C _PyTime_t");
159}
160
Victor Stinner4bfb4602015-03-27 22:27:24 +0100161_PyTime_t
162_PyTime_FromNanoseconds(PY_LONG_LONG ns)
163{
164 _PyTime_t t;
165 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
166 t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
167 return t;
168}
169
Victor Stinnera47b8812015-03-27 18:16:17 +0100170#ifdef HAVE_CLOCK_GETTIME
Victor Stinnercb29f012015-03-27 13:31:18 +0100171static int
Victor Stinnercb0c6022015-03-28 05:24:19 +0100172_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise)
Victor Stinnercb29f012015-03-27 13:31:18 +0100173{
174 _PyTime_t t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100175 int res = 0;
176
Victor Stinnercb29f012015-03-27 13:31:18 +0100177 t = (_PyTime_t)ts->tv_sec * SEC_TO_NS;
178 if (t / SEC_TO_NS != ts->tv_sec) {
Victor Stinnercb0c6022015-03-28 05:24:19 +0100179 if (raise)
180 _PyTime_overflow();
181 res = -1;
Victor Stinnercb29f012015-03-27 13:31:18 +0100182 }
183
184 t += ts->tv_nsec;
185
186 *tp = t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100187 return res;
Victor Stinnercb29f012015-03-27 13:31:18 +0100188}
Victor Stinner1bd18ba2015-03-30 00:25:38 +0200189#elif !defined(MS_WINDOWS)
Victor Stinnera47b8812015-03-27 18:16:17 +0100190static int
Victor Stinnercb0c6022015-03-28 05:24:19 +0100191_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise)
Victor Stinnera47b8812015-03-27 18:16:17 +0100192{
193 _PyTime_t t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100194 int res = 0;
Victor Stinnera47b8812015-03-27 18:16:17 +0100195
196 t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
197 if (t / SEC_TO_NS != tv->tv_sec) {
Victor Stinnercb0c6022015-03-28 05:24:19 +0100198 if (raise)
199 _PyTime_overflow();
200 res = -1;
Victor Stinnera47b8812015-03-27 18:16:17 +0100201 }
202
203 t += (_PyTime_t)tv->tv_usec * US_TO_NS;
204
205 *tp = t;
Victor Stinnercb0c6022015-03-28 05:24:19 +0100206 return res;
Victor Stinnera47b8812015-03-27 18:16:17 +0100207}
Victor Stinnercb29f012015-03-27 13:31:18 +0100208#endif
209
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200210static int
211_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
212 long to_nanoseconds)
Victor Stinnercb29f012015-03-27 13:31:18 +0100213{
214 if (PyFloat_Check(obj)) {
Victor Stinner45cff0c2015-03-30 10:22:16 +0200215 /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
216 volatile double d, err;
Victor Stinnercb29f012015-03-27 13:31:18 +0100217
218 /* convert to a number of nanoseconds */
219 d = PyFloat_AsDouble(obj);
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200220 d *= to_nanoseconds;
Victor Stinnercb29f012015-03-27 13:31:18 +0100221
Victor Stinnera695f832015-03-30 03:57:14 +0200222 if (round == _PyTime_ROUND_CEILING)
Victor Stinnercb29f012015-03-27 13:31:18 +0100223 d = ceil(d);
224 else
225 d = floor(d);
226
227 *t = (_PyTime_t)d;
228 err = d - (double)*t;
229 if (fabs(err) >= 1.0) {
230 _PyTime_overflow();
231 return -1;
232 }
233 return 0;
234 }
235 else {
236#ifdef HAVE_LONG_LONG
237 PY_LONG_LONG sec;
238 sec = PyLong_AsLongLong(obj);
239 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
240#else
241 long sec;
242 sec = PyLong_AsLong(obj);
243 assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
244#endif
245 if (sec == -1 && PyErr_Occurred()) {
246 if (PyErr_ExceptionMatches(PyExc_OverflowError))
247 _PyTime_overflow();
248 return -1;
249 }
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200250 *t = sec * to_nanoseconds;
251 if (*t / to_nanoseconds != sec) {
Victor Stinnercb29f012015-03-27 13:31:18 +0100252 _PyTime_overflow();
253 return -1;
254 }
255 return 0;
256 }
257}
258
Victor Stinnerfa09beb2015-03-30 21:36:10 +0200259int
260_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
261{
262 return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
263}
264
265int
266_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
267{
268 return _PyTime_FromObject(t, obj, round, MS_TO_NS);
269}
270
Victor Stinner4bfb4602015-03-27 22:27:24 +0100271double
272_PyTime_AsSecondsDouble(_PyTime_t t)
273{
274 _PyTime_t sec, ns;
275 /* Divide using integers to avoid rounding issues on the integer part.
276 1e-9 cannot be stored exactly in IEEE 64-bit. */
277 sec = t / SEC_TO_NS;
278 ns = t % SEC_TO_NS;
279 return (double)sec + (double)ns * 1e-9;
280}
281
Victor Stinner992c43f2015-03-27 17:12:45 +0100282PyObject *
283_PyTime_AsNanosecondsObject(_PyTime_t t)
284{
285#ifdef HAVE_LONG_LONG
286 assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
287 return PyLong_FromLongLong((PY_LONG_LONG)t);
288#else
289 assert(sizeof(long) >= sizeof(_PyTime_t));
290 return PyLong_FromLong((long)t);
291#endif
292}
293
Victor Stinnercb29f012015-03-27 13:31:18 +0100294static _PyTime_t
Victor Stinner62d1c702015-04-01 17:47:07 +0200295_PyTime_Divide(_PyTime_t t, _PyTime_t k, _PyTime_round_t round)
Victor Stinnercb29f012015-03-27 13:31:18 +0100296{
Victor Stinner62d1c702015-04-01 17:47:07 +0200297 assert(k > 1);
298 if (round == _PyTime_ROUND_CEILING) {
299 if (t >= 0)
Victor Stinnercb29f012015-03-27 13:31:18 +0100300 return (t + k - 1) / k;
301 else
Victor Stinner62d1c702015-04-01 17:47:07 +0200302 return (t - (k - 1)) / k;
Victor Stinnercb29f012015-03-27 13:31:18 +0100303 }
Victor Stinner62d1c702015-04-01 17:47:07 +0200304 else
305 return t / k;
Victor Stinnercb29f012015-03-27 13:31:18 +0100306}
307
308_PyTime_t
309_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
310{
Victor Stinner62d1c702015-04-01 17:47:07 +0200311 return _PyTime_Divide(t, NS_TO_MS, round);
Victor Stinnercb29f012015-03-27 13:31:18 +0100312}
313
Victor Stinnerf5faad22015-03-28 03:52:05 +0100314_PyTime_t
315_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
316{
Victor Stinner62d1c702015-04-01 17:47:07 +0200317 return _PyTime_Divide(t, NS_TO_US, round);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100318}
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}