pytime.c 17.5 KB
Newer Older
1
#include "Python.h"
2 3 4
#ifdef MS_WINDOWS
#include <windows.h>
#endif
5

6 7 8 9
#if defined(__APPLE__)
#include <mach/mach_time.h>   /* mach_absolute_time(), mach_timebase_info() */
#endif

10 11 12 13 14
#define _PyTime_check_mul_overflow(a, b) \
    (assert(b > 0), \
     (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \
     || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a))

15
/* To millisecond (10^-3) */
16
#define SEC_TO_MS 1000
17 18

/* To microseconds (10^-6) */
19
#define MS_TO_US 1000
20 21 22
#define SEC_TO_US (SEC_TO_MS * MS_TO_US)

/* To nanoseconds (10^-9) */
23
#define US_TO_NS 1000
24 25
#define MS_TO_NS (MS_TO_US * US_TO_NS)
#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
26

27 28 29 30
/* Conversion from nanoseconds */
#define NS_TO_MS (1000 * 1000)
#define NS_TO_US (1000)

31 32 33 34 35 36 37
static void
error_time_t_overflow(void)
{
    PyErr_SetString(PyExc_OverflowError,
                    "timestamp out of range for platform time_t");
}

38
time_t
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
_PyLong_AsTime_t(PyObject *obj)
{
#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
    PY_LONG_LONG val;
    val = PyLong_AsLongLong(obj);
#else
    long val;
    assert(sizeof(time_t) <= sizeof(long));
    val = PyLong_AsLong(obj);
#endif
    if (val == -1 && PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError))
            error_time_t_overflow();
        return -1;
    }
    return (time_t)val;
}

57 58 59 60 61 62 63 64 65 66 67
PyObject *
_PyLong_FromTime_t(time_t t)
{
#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
    return PyLong_FromLongLong((PY_LONG_LONG)t);
#else
    assert(sizeof(time_t) <= sizeof(long));
    return PyLong_FromLong((long)t);
#endif
}

68 69 70
/* Round to nearest with ties going to nearest even integer
   (_PyTime_ROUND_HALF_EVEN) */
static double
71
_PyTime_RoundHalfEven(double x)
72
{
73 74 75 76 77
    double rounded = round(x);
    if (fabs(x-rounded) == 0.5)
        /* halfway case: round to even */
        rounded = 2.0*round(x/2.0);
    return rounded;
78 79
}

80 81 82
static double
_PyTime_Round(double x, _PyTime_round_t round)
{
83 84 85 86
    /* volatile avoids optimization changing how numbers are rounded */
    volatile double d;

    d = x;
87
    if (round == _PyTime_ROUND_HALF_EVEN)
88
        d = _PyTime_RoundHalfEven(d);
89
    else if (round == _PyTime_ROUND_CEILING)
90
        d = ceil(d);
91
    else
92 93
        d = floor(d);
    return d;
94 95
}

96
static int
Victor Stinner's avatar
Victor Stinner committed
97
_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
98
                            double denominator, _PyTime_round_t round)
99
{
Victor Stinner's avatar
Victor Stinner committed
100
    double intpart, err;
101
    /* volatile avoids optimization changing how numbers are rounded */
Victor Stinner's avatar
Victor Stinner committed
102 103 104
    volatile double floatpart;

    floatpart = modf(d, &intpart);
105

Victor Stinner's avatar
Victor Stinner committed
106
    floatpart *= denominator;
107
    floatpart = _PyTime_Round(floatpart, round);
108 109 110
    if (floatpart >= denominator) {
        floatpart -= denominator;
        intpart += 1.0;
Victor Stinner's avatar
Victor Stinner committed
111
    }
112 113 114 115
    else if (floatpart < 0) {
        floatpart += denominator;
        intpart -= 1.0;
    }
116
    assert(0.0 <= floatpart && floatpart < denominator);
117

Victor Stinner's avatar
Victor Stinner committed
118
    *sec = (time_t)intpart;
119 120
    *numerator = (long)floatpart;

Victor Stinner's avatar
Victor Stinner committed
121 122 123 124 125 126 127
    err = intpart - (double)*sec;
    if (err <= -1.0 || err >= 1.0) {
        error_time_t_overflow();
        return -1;
    }
    return 0;
}
128

Victor Stinner's avatar
Victor Stinner committed
129 130 131 132
static int
_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
                            double denominator, _PyTime_round_t round)
{
133 134
    assert(denominator <= (double)LONG_MAX);

Victor Stinner's avatar
Victor Stinner committed
135 136 137 138
    if (PyFloat_Check(obj)) {
        double d = PyFloat_AsDouble(obj);
        return _PyTime_DoubleToDenominator(d, sec, numerator,
                                           denominator, round);
139 140
    }
    else {
141
        *sec = _PyLong_AsTime_t(obj);
142
        *numerator = 0;
143 144 145 146 147 148 149
        if (*sec == (time_t)-1 && PyErr_Occurred())
            return -1;
        return 0;
    }
}

int
150
_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
151 152
{
    if (PyFloat_Check(obj)) {
153
        double intpart, err;
154
        /* volatile avoids optimization changing how numbers are rounded */
155
        volatile double d;
156 157

        d = PyFloat_AsDouble(obj);
158
        d = _PyTime_Round(d, round);
159 160 161 162 163 164 165
        (void)modf(d, &intpart);

        *sec = (time_t)intpart;
        err = intpart - (double)*sec;
        if (err <= -1.0 || err >= 1.0) {
            error_time_t_overflow();
            return -1;
166 167 168
        }
        return 0;
    }
169 170 171 172 173 174 175
    else {
        *sec = _PyLong_AsTime_t(obj);
        if (*sec == (time_t)-1 && PyErr_Occurred())
            return -1;
        return 0;
    }
}
176

177
int
178 179
_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
                         _PyTime_round_t round)
180
{
181 182
    int res;
    res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
183
    assert(0 <= *nsec && *nsec < SEC_TO_NS);
184
    return res;
185 186 187
}

int
188 189
_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
                        _PyTime_round_t round)
190
{
191 192
    int res;
    res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
193
    assert(0 <= *usec && *usec < SEC_TO_US);
194
    return res;
195 196
}

197 198 199 200 201 202 203
static void
_PyTime_overflow(void)
{
    PyErr_SetString(PyExc_OverflowError,
                    "timestamp too large to convert to C _PyTime_t");
}

204 205 206 207
_PyTime_t
_PyTime_FromSeconds(int seconds)
{
    _PyTime_t t;
208
    t = (_PyTime_t)seconds;
209 210 211
    /* ensure that integer overflow cannot happen, int type should have 32
       bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30
       bits). */
212 213 214
    assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS)
           || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS));
    t *= SEC_TO_NS;
215 216 217
    return t;
}

218 219 220 221 222 223 224 225 226
_PyTime_t
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
{
    _PyTime_t t;
    assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
    t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t);
    return t;
}

227
#ifdef HAVE_CLOCK_GETTIME
228
static int
229
_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise)
230 231
{
    _PyTime_t t;
232 233
    int res = 0;

234 235 236 237
    assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t));
    t = (_PyTime_t)ts->tv_sec;

    if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
238 239 240
        if (raise)
            _PyTime_overflow();
        res = -1;
241
    }
242
    t = t * SEC_TO_NS;
243 244 245 246

    t += ts->tv_nsec;

    *tp = t;
247
    return res;
248
}
249
#elif !defined(MS_WINDOWS)
250
static int
251
_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise)
252 253
{
    _PyTime_t t;
254
    int res = 0;
255

256 257 258 259
    assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t));
    t = (_PyTime_t)tv->tv_sec;

    if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
260 261 262
        if (raise)
            _PyTime_overflow();
        res = -1;
263
    }
264
    t = t * SEC_TO_NS;
265 266 267 268

    t += (_PyTime_t)tv->tv_usec * US_TO_NS;

    *tp = t;
269
    return res;
270
}
271 272
#endif

Victor Stinner's avatar
Victor Stinner committed
273 274
static int
_PyTime_FromFloatObject(_PyTime_t *t, double value, _PyTime_round_t round,
275
                        long unit_to_ns)
Victor Stinner's avatar
Victor Stinner committed
276
{
277
    double err;
278
    /* volatile avoids optimization changing how numbers are rounded */
279
    volatile double d;
Victor Stinner's avatar
Victor Stinner committed
280 281 282

    /* convert to a number of nanoseconds */
    d = value;
283 284
    d *= (double)unit_to_ns;
    d = _PyTime_Round(d, round);
Victor Stinner's avatar
Victor Stinner committed
285 286 287 288 289 290 291 292 293 294

    *t = (_PyTime_t)d;
    err = d - (double)*t;
    if (fabs(err) >= 1.0) {
        _PyTime_overflow();
        return -1;
    }
    return 0;
}

295 296
static int
_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
297
                   long unit_to_ns)
298 299
{
    if (PyFloat_Check(obj)) {
Victor Stinner's avatar
Victor Stinner committed
300
        double d;
301
        d = PyFloat_AsDouble(obj);
302
        return _PyTime_FromFloatObject(t, d, round, unit_to_ns);
303 304 305 306 307
    }
    else {
#ifdef HAVE_LONG_LONG
        PY_LONG_LONG sec;
        assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
308 309

        sec = PyLong_AsLongLong(obj);
310 311 312
#else
        long sec;
        assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
313 314

        sec = PyLong_AsLong(obj);
315 316 317 318 319 320
#endif
        if (sec == -1 && PyErr_Occurred()) {
            if (PyErr_ExceptionMatches(PyExc_OverflowError))
                _PyTime_overflow();
            return -1;
        }
321

322
        if (_PyTime_check_mul_overflow(sec, unit_to_ns)) {
323 324 325
            _PyTime_overflow();
            return -1;
        }
326
        *t = sec * unit_to_ns;
327 328 329 330
        return 0;
    }
}

331 332 333 334 335 336 337 338 339 340 341 342
int
_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
{
    return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
}

int
_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
{
    return _PyTime_FromObject(t, obj, round, MS_TO_NS);
}

343 344 345
double
_PyTime_AsSecondsDouble(_PyTime_t t)
{
346 347 348
    /* volatile avoids optimization changing how numbers are rounded */
    volatile double d;

349 350 351 352 353
    if (t % SEC_TO_NS == 0) {
        _PyTime_t secs;
        /* Divide using integers to avoid rounding issues on the integer part.
           1e-9 cannot be stored exactly in IEEE 64-bit. */
        secs = t / SEC_TO_NS;
354
        d = (double)secs;
355 356
    }
    else {
357 358
        d = (double)t;
        d /= 1e9;
359
    }
360
    return d;
361 362
}

363 364 365 366 367 368 369 370 371 372 373 374
PyObject *
_PyTime_AsNanosecondsObject(_PyTime_t t)
{
#ifdef HAVE_LONG_LONG
    assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t));
    return PyLong_FromLongLong((PY_LONG_LONG)t);
#else
    assert(sizeof(long) >= sizeof(_PyTime_t));
    return PyLong_FromLong((long)t);
#endif
}

375
static _PyTime_t
376 377
_PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
               const _PyTime_round_t round)
378
{
379
    assert(k > 1);
380 381
    if (round == _PyTime_ROUND_HALF_EVEN) {
        _PyTime_t x, r, abs_r;
382 383
        x = t / k;
        r = t % k;
384 385
        abs_r = Py_ABS(r);
        if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) {
386 387 388 389 390 391 392 393
            if (t >= 0)
                x++;
            else
                x--;
        }
        return x;
    }
    else if (round == _PyTime_ROUND_CEILING) {
394
        if (t >= 0)
395
            return (t + k - 1) / k;
396 397 398 399 400 401
        else
            return t / k;
    }
    else {
        if (t >= 0)
            return t / k;
402
        else
403
            return (t - (k - 1)) / k;
404 405 406 407 408 409
    }
}

_PyTime_t
_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
{
410
    return _PyTime_Divide(t, NS_TO_MS, round);
411 412
}

413 414 415
_PyTime_t
_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
{
416
    return _PyTime_Divide(t, NS_TO_US, round);
417 418
}

419 420 421
static int
_PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
                       int raise)
422 423
{
    _PyTime_t secs, ns;
424
    int res = 0;
425
    int usec;
426 427 428 429 430 431 432 433

    secs = t / SEC_TO_NS;
    ns = t % SEC_TO_NS;

#ifdef MS_WINDOWS
    tv->tv_sec = (long)secs;
#else
    tv->tv_sec = secs;
434
#endif
435 436
    if ((_PyTime_t)tv->tv_sec != secs)
        res = -1;
437

438 439 440 441
    usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
    if (usec < 0) {
        usec += SEC_TO_US;
        tv->tv_sec -= 1;
442
    }
443
    else if (usec >= SEC_TO_US) {
444
        usec -= SEC_TO_US;
445 446 447
        tv->tv_sec += 1;
    }

448 449 450
    assert(0 <= usec && usec < SEC_TO_US);
    tv->tv_usec = usec;

451
    if (res && raise)
452
        error_time_t_overflow();
453
    return res;
454 455
}

456 457 458 459 460 461 462 463 464 465 466 467
int
_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{
    return _PyTime_AsTimeval_impl(t, tv, round, 1);
}

int
_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{
    return _PyTime_AsTimeval_impl(t, tv, round, 0);
}

468
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
469 470 471
int
_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
{
472 473 474
    _PyTime_t secs, nsec;

    secs = t / SEC_TO_NS;
475 476 477
    nsec = t % SEC_TO_NS;
    if (nsec < 0) {
        nsec += SEC_TO_NS;
478
        secs -= 1;
479
    }
480
    ts->tv_sec = (time_t)secs;
481 482 483
    assert(0 <= nsec && nsec < SEC_TO_NS);
    ts->tv_nsec = nsec;

484
    if ((_PyTime_t)ts->tv_sec != secs) {
485
        error_time_t_overflow();
486 487 488 489 490 491
        return -1;
    }
    return 0;
}
#endif

492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
static int
pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
{
#ifdef MS_WINDOWS
    FILETIME system_time;
    ULARGE_INTEGER large;

    assert(info == NULL || raise);

    GetSystemTimeAsFileTime(&system_time);
    large.u.LowPart = system_time.dwLowDateTime;
    large.u.HighPart = system_time.dwHighDateTime;
    /* 11,644,473,600,000,000,000: number of nanoseconds between
       the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
       days). */
    *tp = large.QuadPart * 100 - 11644473600000000000;
    if (info) {
        DWORD timeAdjustment, timeIncrement;
        BOOL isTimeAdjustmentDisabled, ok;

        info->implementation = "GetSystemTimeAsFileTime()";
        info->monotonic = 0;
        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
                                     &isTimeAdjustmentDisabled);
        if (!ok) {
            PyErr_SetFromWindowsErr(0);
            return -1;
        }
        info->resolution = timeIncrement * 1e-7;
        info->adjustable = 1;
    }

#else   /* MS_WINDOWS */
    int err;
#ifdef HAVE_CLOCK_GETTIME
    struct timespec ts;
#else
    struct timeval tv;
#endif

    assert(info == NULL || raise);

#ifdef HAVE_CLOCK_GETTIME
    err = clock_gettime(CLOCK_REALTIME, &ts);
    if (err) {
        if (raise)
            PyErr_SetFromErrno(PyExc_OSError);
        return -1;
    }
541
    if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
        return -1;

    if (info) {
        struct timespec res;
        info->implementation = "clock_gettime(CLOCK_REALTIME)";
        info->monotonic = 0;
        info->adjustable = 1;
        if (clock_getres(CLOCK_REALTIME, &res) == 0)
            info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
        else
            info->resolution = 1e-9;
    }
#else   /* HAVE_CLOCK_GETTIME */

     /* test gettimeofday() */
#ifdef GETTIMEOFDAY_NO_TZ
    err = gettimeofday(&tv);
#else
    err = gettimeofday(&tv, (struct timezone *)NULL);
#endif
    if (err) {
        if (raise)
            PyErr_SetFromErrno(PyExc_OSError);
        return -1;
    }
567
    if (_PyTime_FromTimeval(tp, &tv, raise) < 0)
568 569 570 571 572 573 574 575 576 577 578 579 580
        return -1;

    if (info) {
        info->implementation = "gettimeofday()";
        info->resolution = 1e-6;
        info->monotonic = 0;
        info->adjustable = 1;
    }
#endif   /* !HAVE_CLOCK_GETTIME */
#endif   /* !MS_WINDOWS */
    return 0;
}

581 582 583 584 585 586 587 588 589 590 591 592 593 594
_PyTime_t
_PyTime_GetSystemClock(void)
{
    _PyTime_t t;
    if (pygettimeofday_new(&t, NULL, 0) < 0) {
        /* should not happen, _PyTime_Init() checked the clock at startup */
        assert(0);

        /* use a fixed value instead of a random value from the stack */
        t = 0;
    }
    return t;
}

595 596 597 598 599 600
int
_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
{
    return pygettimeofday_new(t, info, 1);
}

601
static int
602
pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
603 604
{
#if defined(MS_WINDOWS)
605 606
    ULONGLONG ticks;
    _PyTime_t t;
607 608 609

    assert(info == NULL || raise);

610 611 612
    ticks = GetTickCount64();
    assert(sizeof(result) <= sizeof(_PyTime_t));
    t = (_PyTime_t)ticks;
613

614
    if (_PyTime_check_mul_overflow(t, MS_TO_NS)) {
615 616 617 618 619 620 621
        if (raise) {
            _PyTime_overflow();
            return -1;
        }
        /* Hello, time traveler! */
        assert(0);
    }
622
    *tp = t * MS_TO_NS;
623 624 625 626

    if (info) {
        DWORD timeAdjustment, timeIncrement;
        BOOL isTimeAdjustmentDisabled, ok;
627
        info->implementation = "GetTickCount64()";
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
        info->monotonic = 1;
        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
                                     &isTimeAdjustmentDisabled);
        if (!ok) {
            PyErr_SetFromWindowsErr(0);
            return -1;
        }
        info->resolution = timeIncrement * 1e-7;
        info->adjustable = 0;
    }

#elif defined(__APPLE__)
    static mach_timebase_info_data_t timebase;
    uint64_t time;

    if (timebase.denom == 0) {
        /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
           fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
        (void)mach_timebase_info(&timebase);
    }

    time = mach_absolute_time();

    /* apply timebase factor */
    time *= timebase.numer;
    time /= timebase.denom;

    *tp = time;

    if (info) {
        info->implementation = "mach_absolute_time()";
        info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
        info->monotonic = 1;
        info->adjustable = 0;
    }

#else
    struct timespec ts;
#ifdef CLOCK_HIGHRES
    const clockid_t clk_id = CLOCK_HIGHRES;
    const char *implementation = "clock_gettime(CLOCK_HIGHRES)";
#else
    const clockid_t clk_id = CLOCK_MONOTONIC;
    const char *implementation = "clock_gettime(CLOCK_MONOTONIC)";
#endif

    assert(info == NULL || raise);

    if (clock_gettime(clk_id, &ts) != 0) {
        if (raise) {
            PyErr_SetFromErrno(PyExc_OSError);
            return -1;
        }
        return -1;
    }

    if (info) {
        struct timespec res;
        info->monotonic = 1;
        info->implementation = implementation;
        info->adjustable = 0;
        if (clock_getres(clk_id, &res) != 0) {
            PyErr_SetFromErrno(PyExc_OSError);
            return -1;
        }
        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
    }
695
    if (_PyTime_FromTimespec(tp, &ts, raise) < 0)
696 697 698 699 700 701 702 703 704
        return -1;
#endif
    return 0;
}

_PyTime_t
_PyTime_GetMonotonicClock(void)
{
    _PyTime_t t;
705
    if (pymonotonic(&t, NULL, 0) < 0) {
706 707
        /* should not happen, _PyTime_Init() checked that monotonic clock at
           startup */
708
        assert(0);
709 710

        /* use a fixed value instead of a random value from the stack */
711 712 713 714 715
        t = 0;
    }
    return t;
}

716 717 718
int
_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
{
719
    return pymonotonic(tp, info, 1);
720 721
}

722 723
int
_PyTime_Init(void)
724
{
725 726
    _PyTime_t t;

727 728
    /* ensure that the system clock works */
    if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
729
        return -1;
730

731
    /* ensure that the operating system provides a monotonic clock */
732
    if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
733
        return -1;
734 735 736 737

    /* check that _PyTime_FromSeconds() cannot overflow */
    assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS);
    assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS);
738
    return 0;
739
}