[Python-checkins] bpo-21302: Add _PyTime_AsNanoseconds() (GH-28350)

vstinner webhook-mailer at python.org
Wed Sep 15 08:26:53 EDT 2021


https://github.com/python/cpython/commit/b49263b698993cad2b8aaddc55cdeaa678412b30
commit: b49263b698993cad2b8aaddc55cdeaa678412b30
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2021-09-15T14:26:43+02:00
summary:

bpo-21302: Add _PyTime_AsNanoseconds() (GH-28350)

Refactor pytime.c:

* Add pytime_from_nanoseconds() and pytime_as_nanoseconds(),
  and use explicitly these functions
* Add two empty lines between functions
* PEP 7: add braces { ... }
* C99: declare variables where they are set
* Rename private functions to lowercase
* Rename error_time_t_overflow() to pytime_time_t_overflow()
* Rename win_perf_counter_frequency() to py_win_perf_counter_frequency()
* py_get_monotonic_clock(): add an assertion to detect overflow when
  mach_absolute_time() unsigned uint64_t is casted to _PyTime_t
  (signed int64_t).

_testcapi: use _PyTime_FromNanoseconds().

files:
M Include/cpython/pytime.h
M Modules/_testcapimodule.c
M Modules/timemodule.c
M Python/pytime.c

diff --git a/Include/cpython/pytime.h b/Include/cpython/pytime.h
index 56607d199ed54..b0453884398cb 100644
--- a/Include/cpython/pytime.h
+++ b/Include/cpython/pytime.h
@@ -111,6 +111,9 @@ PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
 PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
     _PyTime_round_t round);
 
+/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */
+PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t);
+
 /* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
    object. */
 PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index b1e64f19f2d14..51323f03e2368 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -4623,11 +4623,10 @@ static PyObject *
 test_pytime_fromseconds(PyObject *self, PyObject *args)
 {
     int seconds;
-    _PyTime_t ts;
-
-    if (!PyArg_ParseTuple(args, "i", &seconds))
+    if (!PyArg_ParseTuple(args, "i", &seconds)) {
         return NULL;
-    ts = _PyTime_FromSeconds(seconds);
+    }
+    _PyTime_t ts = _PyTime_FromSeconds(seconds);
     return _PyTime_AsNanosecondsObject(ts);
 }
 
@@ -4636,14 +4635,16 @@ test_pytime_fromsecondsobject(PyObject *self, PyObject *args)
 {
     PyObject *obj;
     int round;
-    _PyTime_t ts;
-
-    if (!PyArg_ParseTuple(args, "Oi", &obj, &round))
+    if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) {
         return NULL;
-    if (check_time_rounding(round) < 0)
+    }
+    if (check_time_rounding(round) < 0) {
         return NULL;
-    if (_PyTime_FromSecondsObject(&ts, obj, round) == -1)
+    }
+    _PyTime_t ts;
+    if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) {
         return NULL;
+    }
     return _PyTime_AsNanosecondsObject(ts);
 }
 
@@ -4651,16 +4652,14 @@ static PyObject *
 test_pytime_assecondsdouble(PyObject *self, PyObject *args)
 {
     PyObject *obj;
-    _PyTime_t ts;
-    double d;
-
     if (!PyArg_ParseTuple(args, "O", &obj)) {
         return NULL;
     }
+    _PyTime_t ts;
     if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) {
         return NULL;
     }
-    d = _PyTime_AsSecondsDouble(ts);
+    double d = _PyTime_AsSecondsDouble(ts);
     return PyFloat_FromDouble(d);
 }
 
@@ -4669,23 +4668,22 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args)
 {
     PyObject *obj;
     int round;
-    _PyTime_t t;
-    struct timeval tv;
-    PyObject *seconds;
-
-    if (!PyArg_ParseTuple(args, "Oi", &obj, &round))
+    if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) {
         return NULL;
+    }
     if (check_time_rounding(round) < 0) {
         return NULL;
     }
+    _PyTime_t t;
     if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
         return NULL;
     }
+    struct timeval tv;
     if (_PyTime_AsTimeval(t, &tv, round) < 0) {
         return NULL;
     }
 
-    seconds = PyLong_FromLongLong(tv.tv_sec);
+    PyObject *seconds = PyLong_FromLongLong(tv.tv_sec);
     if (seconds == NULL) {
         return NULL;
     }
@@ -4697,15 +4695,14 @@ static PyObject *
 test_PyTime_AsTimespec(PyObject *self, PyObject *args)
 {
     PyObject *obj;
-    _PyTime_t t;
-    struct timespec ts;
-
     if (!PyArg_ParseTuple(args, "O", &obj)) {
         return NULL;
     }
+    _PyTime_t t;
     if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
         return NULL;
     }
+    struct timespec ts;
     if (_PyTime_AsTimespec(t, &ts) == -1) {
         return NULL;
     }
@@ -4718,21 +4715,19 @@ test_PyTime_AsMilliseconds(PyObject *self, PyObject *args)
 {
     PyObject *obj;
     int round;
-    _PyTime_t t, ms;
-
     if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) {
         return NULL;
     }
+    _PyTime_t t;
     if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
         return NULL;
     }
     if (check_time_rounding(round) < 0) {
         return NULL;
     }
-    ms = _PyTime_AsMilliseconds(t, round);
-    /* This conversion rely on the fact that _PyTime_t is a number of
-       nanoseconds */
-    return _PyTime_AsNanosecondsObject(ms);
+    _PyTime_t ms = _PyTime_AsMilliseconds(t, round);
+    _PyTime_t ns = _PyTime_FromNanoseconds(ms);
+    return _PyTime_AsNanosecondsObject(ns);
 }
 
 static PyObject *
@@ -4740,20 +4735,19 @@ test_PyTime_AsMicroseconds(PyObject *self, PyObject *args)
 {
     PyObject *obj;
     int round;
-    _PyTime_t t, ms;
-
-    if (!PyArg_ParseTuple(args, "Oi", &obj, &round))
+    if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) {
         return NULL;
+    }
+    _PyTime_t t;
     if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
         return NULL;
     }
     if (check_time_rounding(round) < 0) {
         return NULL;
     }
-    ms = _PyTime_AsMicroseconds(t, round);
-    /* This conversion rely on the fact that _PyTime_t is a number of
-       nanoseconds */
-    return _PyTime_AsNanosecondsObject(ms);
+    _PyTime_t us = _PyTime_AsMicroseconds(t, round);
+    _PyTime_t ns = _PyTime_FromNanoseconds(us);
+    return _PyTime_AsNanosecondsObject(ns);
 }
 
 static PyObject*
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index cf58a18caf1f2..52c61154f3a05 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -128,12 +128,11 @@ static int
 _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
 {
     static int initialized = 0;
-    clock_t ticks;
 
     if (!initialized) {
         initialized = 1;
 
-        /* must sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
+        /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
            above cannot overflow */
         if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) {
             PyErr_SetString(PyExc_OverflowError,
@@ -149,14 +148,15 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
         info->adjustable = 0;
     }
 
-    ticks = clock();
+    clock_t ticks = clock();
     if (ticks == (clock_t)-1) {
         PyErr_SetString(PyExc_RuntimeError,
                         "the processor time used is not available "
                         "or its value cannot be represented");
         return -1;
     }
-    *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
+    _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
+    *tp = _PyTime_FromNanoseconds(ns);
     return 0;
 }
 #endif /* HAVE_CLOCK */
@@ -1325,10 +1325,10 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
                 info->resolution = 1.0 / (double)ticks_per_second;
             }
 
-            _PyTime_t total;
-            total = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
-            total += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
-            *tp = total;
+            _PyTime_t ns;
+            ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
+            ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
+            *tp = _PyTime_FromNanoseconds(ns);
             return 0;
         }
     }
diff --git a/Python/pytime.c b/Python/pytime.c
index 1ef99aee74846..8035a5f8a28b4 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -34,21 +34,39 @@
 #define NS_TO_MS (1000 * 1000)
 #define NS_TO_US (1000)
 
+
 static void
-error_time_t_overflow(void)
+pytime_time_t_overflow(void)
 {
     PyErr_SetString(PyExc_OverflowError,
                     "timestamp out of range for platform time_t");
 }
 
+
 static void
-_PyTime_overflow(void)
+pytime_overflow(void)
 {
     PyErr_SetString(PyExc_OverflowError,
                     "timestamp too large to convert to C _PyTime_t");
 }
 
 
+static inline _PyTime_t
+pytime_from_nanoseconds(_PyTime_t t)
+{
+    // _PyTime_t is a number of nanoseconds
+    return t;
+}
+
+
+static inline _PyTime_t
+pytime_as_nanoseconds(_PyTime_t t)
+{
+    // _PyTime_t is a number of nanoseconds
+    return t;
+}
+
+
 _PyTime_t
 _PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div)
 {
@@ -80,13 +98,14 @@ _PyLong_AsTime_t(PyObject *obj)
 #endif
     if (val == -1 && PyErr_Occurred()) {
         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
-            error_time_t_overflow();
+            pytime_time_t_overflow();
         }
         return -1;
     }
     return (time_t)val;
 }
 
+
 PyObject *
 _PyLong_FromTime_t(time_t t)
 {
@@ -98,28 +117,30 @@ _PyLong_FromTime_t(time_t t)
 #endif
 }
 
+
 /* Round to nearest with ties going to nearest even integer
    (_PyTime_ROUND_HALF_EVEN) */
 static double
-_PyTime_RoundHalfEven(double x)
+pytime_round_half_even(double x)
 {
     double rounded = round(x);
     if (fabs(x-rounded) == 0.5) {
         /* halfway case: round to even */
-        rounded = 2.0*round(x/2.0);
+        rounded = 2.0 * round(x / 2.0);
     }
     return rounded;
 }
 
+
 static double
-_PyTime_Round(double x, _PyTime_round_t round)
+pytime_round(double x, _PyTime_round_t round)
 {
     /* volatile avoids optimization changing how numbers are rounded */
     volatile double d;
 
     d = x;
     if (round == _PyTime_ROUND_HALF_EVEN) {
-        d = _PyTime_RoundHalfEven(d);
+        d = pytime_round_half_even(d);
     }
     else if (round == _PyTime_ROUND_CEILING) {
         d = ceil(d);
@@ -134,9 +155,10 @@ _PyTime_Round(double x, _PyTime_round_t round)
     return d;
 }
 
+
 static int
-_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
-                            long idenominator, _PyTime_round_t round)
+pytime_double_to_denominator(double d, time_t *sec, long *numerator,
+                             long idenominator, _PyTime_round_t round)
 {
     double denominator = (double)idenominator;
     double intpart;
@@ -146,7 +168,7 @@ _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
     floatpart = modf(d, &intpart);
 
     floatpart *= denominator;
-    floatpart = _PyTime_Round(floatpart, round);
+    floatpart = pytime_round(floatpart, round);
     if (floatpart >= denominator) {
         floatpart -= denominator;
         intpart += 1.0;
@@ -158,7 +180,7 @@ _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
     assert(0.0 <= floatpart && floatpart < denominator);
 
     if (!_Py_InIntegralTypeRange(time_t, intpart)) {
-        error_time_t_overflow();
+        pytime_time_t_overflow();
         return -1;
     }
     *sec = (time_t)intpart;
@@ -167,9 +189,10 @@ _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
     return 0;
 }
 
+
 static int
-_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
-                            long denominator, _PyTime_round_t round)
+pytime_object_to_denominator(PyObject *obj, time_t *sec, long *numerator,
+                             long denominator, _PyTime_round_t round)
 {
     assert(denominator >= 1);
 
@@ -180,8 +203,8 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
             PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
             return -1;
         }
-        return _PyTime_DoubleToDenominator(d, sec, numerator,
-                                           denominator, round);
+        return pytime_double_to_denominator(d, sec, numerator,
+                                            denominator, round);
     }
     else {
         *sec = _PyLong_AsTime_t(obj);
@@ -193,6 +216,7 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
     }
 }
 
+
 int
 _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
 {
@@ -207,11 +231,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
             return -1;
         }
 
-        d = _PyTime_Round(d, round);
+        d = pytime_round(d, round);
         (void)modf(d, &intpart);
 
         if (!_Py_InIntegralTypeRange(time_t, intpart)) {
-            error_time_t_overflow();
+            pytime_time_t_overflow();
             return -1;
         }
         *sec = (time_t)intpart;
@@ -226,49 +250,50 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
     }
 }
 
+
 int
 _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
                          _PyTime_round_t round)
 {
-    return _PyTime_ObjectToDenominator(obj, sec, nsec, SEC_TO_NS, round);
+    return pytime_object_to_denominator(obj, sec, nsec, SEC_TO_NS, round);
 }
 
+
 int
 _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
                         _PyTime_round_t round)
 {
-    return _PyTime_ObjectToDenominator(obj, sec, usec, SEC_TO_US, round);
+    return pytime_object_to_denominator(obj, sec, usec, SEC_TO_US, round);
 }
 
+
 _PyTime_t
 _PyTime_FromSeconds(int seconds)
 {
-    _PyTime_t t;
     /* 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). */
     Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS);
     Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS);
 
-    t = (_PyTime_t)seconds;
+    _PyTime_t t = (_PyTime_t)seconds;
     assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS)
            || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS));
     t *= SEC_TO_NS;
-    return t;
+    return pytime_from_nanoseconds(t);
 }
 
+
 _PyTime_t
 _PyTime_FromNanoseconds(_PyTime_t ns)
 {
-    /* _PyTime_t already uses nanosecond resolution, no conversion needed */
-    return ns;
+    return pytime_from_nanoseconds(ns);
 }
 
+
 int
 _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj)
 {
-    long long nsec;
-    _PyTime_t t;
 
     if (!PyLong_Check(obj)) {
         PyErr_Format(PyExc_TypeError, "expect int, got %s",
@@ -277,25 +302,25 @@ _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj)
     }
 
     Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t));
-    nsec = PyLong_AsLongLong(obj);
+    long long nsec = PyLong_AsLongLong(obj);
     if (nsec == -1 && PyErr_Occurred()) {
         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
-            _PyTime_overflow();
+            pytime_overflow();
         }
         return -1;
     }
 
-    /* _PyTime_t already uses nanosecond resolution, no conversion needed */
-    t = (_PyTime_t)nsec;
-    *tp = t;
+    _PyTime_t t = (_PyTime_t)nsec;
+    *tp = pytime_from_nanoseconds(t);
     return 0;
 }
 
+
 #ifdef HAVE_CLOCK_GETTIME
 static int
 pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise)
 {
-    _PyTime_t t, nsec;
+    _PyTime_t t, tv_nsec;
     int res = 0;
 
     Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t));
@@ -303,7 +328,7 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise)
 
     if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
         if (raise) {
-            _PyTime_overflow();
+            pytime_overflow();
             res = -1;
         }
         t = (t > 0) ? _PyTime_MAX : _PyTime_MIN;
@@ -312,21 +337,21 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise)
         t = t * SEC_TO_NS;
     }
 
-    nsec = ts->tv_nsec;
-    /* The following test is written for positive only nsec */
-    assert(nsec >= 0);
-    if (t > _PyTime_MAX - nsec) {
+    tv_nsec = ts->tv_nsec;
+    /* The following test is written for positive only tv_nsec */
+    assert(tv_nsec >= 0);
+    if (t > _PyTime_MAX - tv_nsec) {
         if (raise) {
-            _PyTime_overflow();
+            pytime_overflow();
             res = -1;
         }
         t = _PyTime_MAX;
     }
     else {
-        t += nsec;
+        t += tv_nsec;
     }
 
-    *tp = t;
+    *tp = pytime_from_nanoseconds(t);
     return res;
 }
 
@@ -337,6 +362,7 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
 }
 #endif
 
+
 #if !defined(MS_WINDOWS)
 static int
 pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise)
@@ -349,7 +375,7 @@ pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise)
 
     if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) {
         if (raise) {
-            _PyTime_overflow();
+            pytime_overflow();
             res = -1;
         }
         t = (t > 0) ? _PyTime_MAX : _PyTime_MIN;
@@ -363,7 +389,7 @@ pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise)
     assert(usec >= 0);
     if (t > _PyTime_MAX - usec) {
         if (raise) {
-            _PyTime_overflow();
+            pytime_overflow();
             res = -1;
         }
         t = _PyTime_MAX;
@@ -372,10 +398,11 @@ pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise)
         t += usec;
     }
 
-    *tp = t;
+    *tp = pytime_from_nanoseconds(t);
     return res;
 }
 
+
 int
 _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
 {
@@ -383,8 +410,9 @@ _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
 }
 #endif
 
+
 static int
-_PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round,
+pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round,
                    long unit_to_ns)
 {
     /* volatile avoids optimization changing how numbers are rounded */
@@ -393,18 +421,21 @@ _PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round,
     /* convert to a number of nanoseconds */
     d = value;
     d *= (double)unit_to_ns;
-    d = _PyTime_Round(d, round);
+    d = pytime_round(d, round);
 
     if (!_Py_InIntegralTypeRange(_PyTime_t, d)) {
-        _PyTime_overflow();
+        pytime_overflow();
         return -1;
     }
-    *t = (_PyTime_t)d;
+    _PyTime_t ns = (_PyTime_t)d;
+
+    *tp = pytime_from_nanoseconds(ns);
     return 0;
 }
 
+
 static int
-_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
+pytime_from_object(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round,
                    long unit_to_ns)
 {
     if (PyFloat_Check(obj)) {
@@ -414,71 +445,77 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
             PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
             return -1;
         }
-        return _PyTime_FromDouble(t, d, round, unit_to_ns);
+        return pytime_from_double(tp, d, round, unit_to_ns);
     }
     else {
-        long long sec;
         Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t));
-
-        sec = PyLong_AsLongLong(obj);
+        long long sec = PyLong_AsLongLong(obj);
         if (sec == -1 && PyErr_Occurred()) {
             if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
-                _PyTime_overflow();
+                pytime_overflow();
             }
             return -1;
         }
 
         if (_PyTime_check_mul_overflow(sec, unit_to_ns)) {
-            _PyTime_overflow();
+            pytime_overflow();
             return -1;
         }
-        *t = sec * unit_to_ns;
+        _PyTime_t ns = sec * unit_to_ns;
+
+        *tp = pytime_from_nanoseconds(ns);
         return 0;
     }
 }
 
+
 int
-_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
+_PyTime_FromSecondsObject(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
 {
-    return _PyTime_FromObject(t, obj, round, SEC_TO_NS);
+    return pytime_from_object(tp, obj, round, SEC_TO_NS);
 }
 
+
 int
-_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round)
+_PyTime_FromMillisecondsObject(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round)
 {
-    return _PyTime_FromObject(t, obj, round, MS_TO_NS);
+    return pytime_from_object(tp, obj, round, MS_TO_NS);
 }
 
+
 double
 _PyTime_AsSecondsDouble(_PyTime_t t)
 {
     /* volatile avoids optimization changing how numbers are rounded */
     volatile double d;
 
-    if (t % SEC_TO_NS == 0) {
-        _PyTime_t secs;
+    _PyTime_t ns = pytime_as_nanoseconds(t);
+    if (ns % SEC_TO_NS == 0) {
         /* 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;
+        _PyTime_t secs = ns / SEC_TO_NS;
         d = (double)secs;
     }
     else {
-        d = (double)t;
+        d = (double)ns;
         d /= 1e9;
     }
     return d;
 }
 
+
 PyObject *
 _PyTime_AsNanosecondsObject(_PyTime_t t)
 {
+    _PyTime_t ns =  pytime_as_nanoseconds(t);
     Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t));
-    return PyLong_FromLongLong((long long)t);
+    return PyLong_FromLongLong((long long)ns);
 }
 
+
 static _PyTime_t
-_PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
-               const _PyTime_round_t round)
+pytime_divide(const _PyTime_t t, const _PyTime_t k,
+              const _PyTime_round_t round)
 {
     assert(k > 1);
     if (round == _PyTime_ROUND_HALF_EVEN) {
@@ -523,66 +560,77 @@ _PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
     }
 }
 
+
 _PyTime_t
-_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
+_PyTime_AsNanoseconds(_PyTime_t t)
 {
-    return _PyTime_Divide(t, NS_TO_MS, round);
+    return pytime_as_nanoseconds(t);
 }
 
+
 _PyTime_t
 _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
 {
-    return _PyTime_Divide(t, NS_TO_US, round);
+    _PyTime_t ns = pytime_as_nanoseconds(t);
+    return pytime_divide(ns, NS_TO_US, round);
 }
 
-static int
-_PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us,
-                       _PyTime_round_t round)
+
+_PyTime_t
+_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round)
 {
-    _PyTime_t secs, ns;
-    int usec;
-    int res = 0;
+    _PyTime_t ns = pytime_as_nanoseconds(t);
+    return pytime_divide(ns, NS_TO_MS, round);
+}
 
-    secs = t / SEC_TO_NS;
-    ns = t % SEC_TO_NS;
 
-    usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
-    if (usec < 0) {
-        usec += SEC_TO_US;
-        if (secs != _PyTime_MIN) {
-            secs -= 1;
+static int
+pytime_as_timeval(_PyTime_t t, _PyTime_t *p_secs, int *p_us,
+                  _PyTime_round_t round)
+{
+    _PyTime_t ns, tv_sec;
+    ns = pytime_as_nanoseconds(t);
+    tv_sec = ns / SEC_TO_NS;
+    ns = ns % SEC_TO_NS;
+
+    int tv_usec = (int)pytime_divide(ns, US_TO_NS, round);
+    int res = 0;
+    if (tv_usec < 0) {
+        tv_usec += SEC_TO_US;
+        if (tv_sec != _PyTime_MIN) {
+            tv_sec -= 1;
         }
         else {
             res = -1;
         }
     }
-    else if (usec >= SEC_TO_US) {
-        usec -= SEC_TO_US;
-        if (secs != _PyTime_MAX) {
-            secs += 1;
+    else if (tv_usec >= SEC_TO_US) {
+        tv_usec -= SEC_TO_US;
+        if (tv_sec != _PyTime_MAX) {
+            tv_sec += 1;
         }
         else {
             res = -1;
         }
     }
-    assert(0 <= usec && usec < SEC_TO_US);
+    assert(0 <= tv_usec && tv_usec < SEC_TO_US);
 
-    *p_secs = secs;
-    *p_us = usec;
+    *p_secs = tv_sec;
+    *p_us = tv_usec;
 
     return res;
 }
 
+
 static int
-_PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv,
-                             _PyTime_round_t round, int raise)
+pytime_as_timeval_struct(_PyTime_t t, struct timeval *tv,
+                         _PyTime_round_t round, int raise)
 {
     _PyTime_t secs, secs2;
     int us;
     int res;
 
-    res = _PyTime_AsTimeval_impl(t, &secs, &us, round);
-
+    res = pytime_as_timeval(t, &secs, &us, round);
 #ifdef MS_WINDOWS
     tv->tv_sec = (long)secs;
 #else
@@ -593,38 +641,39 @@ _PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv,
     secs2 = (_PyTime_t)tv->tv_sec;
     if (res < 0 || secs2 != secs) {
         if (raise) {
-            error_time_t_overflow();
+            pytime_time_t_overflow();
         }
         return -1;
     }
     return 0;
 }
 
+
 int
 _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
 {
-    return _PyTime_AsTimevalStruct_impl(t, tv, round, 1);
+    return pytime_as_timeval_struct(t, tv, round, 1);
 }
 
+
 int
 _PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
 {
-    return _PyTime_AsTimevalStruct_impl(t, tv, round, 0);
+    return pytime_as_timeval_struct(t, tv, round, 0);
 }
 
+
 int
 _PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
                         _PyTime_round_t round)
 {
     _PyTime_t secs;
-    int res;
+    int res = pytime_as_timeval(t, &secs, us, round);
 
-    res = _PyTime_AsTimeval_impl(t, &secs, us, round);
-
-    *p_secs = secs;
+    *p_secs = (time_t)secs;
 
     if (res < 0 || (_PyTime_t)*p_secs != secs) {
-        error_time_t_overflow();
+        pytime_time_t_overflow();
         return -1;
     }
     return 0;
@@ -635,26 +684,28 @@ _PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
 int
 _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
 {
-    _PyTime_t secs, nsec;
+    _PyTime_t tv_sec, tv_nsec;
 
-    secs = t / SEC_TO_NS;
-    nsec = t % SEC_TO_NS;
-    if (nsec < 0) {
-        nsec += SEC_TO_NS;
-        secs -= 1;
+    _PyTime_t ns = pytime_as_nanoseconds(t);
+    tv_sec = ns / SEC_TO_NS;
+    tv_nsec = ns % SEC_TO_NS;
+    if (tv_nsec < 0) {
+        tv_nsec += SEC_TO_NS;
+        tv_sec -= 1;
     }
-    ts->tv_sec = (time_t)secs;
-    assert(0 <= nsec && nsec < SEC_TO_NS);
-    ts->tv_nsec = nsec;
+    ts->tv_sec = (time_t)tv_sec;
+    assert(0 <= tv_nsec && tv_nsec < SEC_TO_NS);
+    ts->tv_nsec = tv_nsec;
 
-    if ((_PyTime_t)ts->tv_sec != secs) {
-        error_time_t_overflow();
+    if ((_PyTime_t)ts->tv_sec != tv_sec) {
+        pytime_time_t_overflow();
         return -1;
     }
     return 0;
 }
 #endif
 
+
 static int
 py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
 {
@@ -670,7 +721,8 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
     /* 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;
+    _PyTime_t ns = large.QuadPart * 100 - 11644473600000000000;
+    *tp = pytime_from_nanoseconds(ns);
     if (info) {
         DWORD timeAdjustment, timeIncrement;
         BOOL isTimeAdjustmentDisabled, ok;
@@ -730,7 +782,8 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
     }
 
 #ifdef HAVE_CLOCK_GETTIME_RUNTIME
-    } else {
+    }
+    else {
 #endif
 
 #endif
@@ -765,6 +818,7 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
     return 0;
 }
 
+
 _PyTime_t
 _PyTime_GetSystemClock(void)
 {
@@ -777,12 +831,14 @@ _PyTime_GetSystemClock(void)
     return t;
 }
 
+
 int
 _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
 {
     return py_get_system_clock(t, info, 1);
 }
 
+
 #if __APPLE__
 static int
 py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise)
@@ -848,7 +904,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
 
     if (_PyTime_check_mul_overflow(t, MS_TO_NS)) {
         if (raise) {
-            _PyTime_overflow();
+            pytime_overflow();
             return -1;
         }
         // Truncate to _PyTime_MAX silently.
@@ -889,8 +945,13 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
         info->adjustable = 0;
     }
 
-    uint64_t ticks = mach_absolute_time();
-    *tp = _PyTime_MulDiv((_PyTime_t)ticks, timebase_numer, timebase_denom);
+    uint64_t uticks = mach_absolute_time();
+    // unsigned => signed
+    assert(uticks <= (uint64_t)_PyTime_MAX);
+    _PyTime_t ticks = (_PyTime_t)uticks;
+
+    _PyTime_t ns = _PyTime_MulDiv(ticks, timebase_numer, timebase_denom);
+    *tp = pytime_from_nanoseconds(ns);
 
 #elif defined(__hpux)
     hrtime_t time;
@@ -903,7 +964,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
         return -1;
     }
 
-    *tp = time;
+    *tp = pytime_from_nanoseconds(time);
 
     if (info) {
         info->implementation = "gethrtime()";
@@ -950,6 +1011,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
     return 0;
 }
 
+
 _PyTime_t
 _PyTime_GetMonotonicClock(void)
 {
@@ -962,6 +1024,7 @@ _PyTime_GetMonotonicClock(void)
     return t;
 }
 
+
 int
 _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
 {
@@ -971,7 +1034,7 @@ _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
 
 #ifdef MS_WINDOWS
 static int
-win_perf_counter_frequency(LONGLONG *pfrequency, int raise)
+py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise)
 {
     LONGLONG frequency;
 
@@ -1025,7 +1088,7 @@ py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
 {
     static LONGLONG frequency = 0;
     if (frequency == 0) {
-        if (win_perf_counter_frequency(&frequency, raise) < 0) {
+        if (py_win_perf_counter_frequency(&frequency, raise) < 0) {
             return -1;
         }
     }
@@ -1047,7 +1110,8 @@ py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
     Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks));
     ticks = (_PyTime_t)ticksll;
 
-    *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency);
+    _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency);
+    *tp = pytime_from_nanoseconds(ns);
     return 0;
 }
 #endif
@@ -1075,8 +1139,8 @@ _PyTime_GetPerfCounter(void)
     res = py_get_monotonic_clock(&t, NULL, 0);
 #endif
     if (res  < 0) {
-        // If win_perf_counter_frequency() or py_get_monotonic_clock() fails:
-        // silently ignore the failure and return 0.
+        // If py_win_perf_counter_frequency() or py_get_monotonic_clock()
+        // fails: silently ignore the failure and return 0.
         t = 0;
     }
     return t;
@@ -1121,6 +1185,7 @@ _PyTime_localtime(time_t t, struct tm *tm)
 #endif /* MS_WINDOWS */
 }
 
+
 int
 _PyTime_gmtime(time_t t, struct tm *tm)
 {



More information about the Python-checkins mailing list