Skip to content

bpo-21302: Add _PyTime_AsNanoseconds() #28350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Include/cpython/pytime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
64 changes: 29 additions & 35 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -4636,31 +4635,31 @@ 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);
}

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);
}

Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -4718,42 +4715,39 @@ 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 *
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*
Expand Down
16 changes: 8 additions & 8 deletions Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}
}
Expand Down
Loading