Issue #22117: time.time() now uses the new _PyTime_t API

* Add _PyTime_GetSystemClockWithInfo()
This commit is contained in:
Victor Stinner 2015-03-27 18:16:17 +01:00
parent 4bfb460d88
commit a47b881d86
3 changed files with 133 additions and 12 deletions

View File

@ -145,6 +145,14 @@ PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
struct timeval *tv,
_PyTime_round_t round);
/* Get the current time from the system clock.
* Fill clock information if info is not NULL.
* Raise an exception and return -1 on error, return 0 on success.
*/
PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
_PyTime_t *t,
_Py_clock_info_t *info);
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
The clock is not affected by system clock updates. The reference point of
the returned value is undefined, so that only the difference between the

View File

@ -1372,12 +1372,14 @@ PyInit_time(void)
static PyObject*
floattime(_Py_clock_info_t *info)
{
_PyTime_timeval t;
if (_PyTime_gettimeofday_info(&t, info) < 0) {
_PyTime_t t;
double d;
if (_PyTime_GetSystemClockWithInfo(&t, info) < 0) {
assert(info != NULL);
return NULL;
}
return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6);
d = _PyTime_AsSecondsDouble(t);
return PyFloat_FromDouble(d);
}

View File

@ -119,12 +119,6 @@ _PyTime_gettimeofday(_PyTime_timeval *tp)
}
}
int
_PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
{
return pygettimeofday(tp, info, 1);
}
static int
pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
{
@ -414,7 +408,7 @@ _PyTime_FromNanoseconds(PY_LONG_LONG ns)
return t;
}
#if !defined(MS_WINDOWS) && !defined(__APPLE__)
#ifdef HAVE_CLOCK_GETTIME
static int
_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
{
@ -430,6 +424,23 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
*tp = t;
return 0;
}
#else
static int
_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
{
_PyTime_t t;
t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
if (t / SEC_TO_NS != tv->tv_sec) {
_PyTime_overflow();
return -1;
}
t += (_PyTime_t)tv->tv_usec * US_TO_NS;
*tp = t;
return 0;
}
#endif
int
@ -561,6 +572,102 @@ _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
return 0;
}
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;
}
if (_PyTime_FromTimespec(tp, &ts) < 0)
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;
}
if (_PyTime_FromTimeval(tp, &tv) < 0)
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;
}
int
_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
{
return pygettimeofday_new(t, info, 1);
}
static int
pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
{
@ -693,7 +800,11 @@ _PyTime_Init(void)
_PyTime_t t;
/* ensure that the system clock works */
if (_PyTime_gettimeofday_info(&tv, NULL) < 0)
if (pygettimeofday(&tv, NULL, 1) < 0)
return -1;
/* ensure that the system clock works */
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
return -1;
/* ensure that the operating system provides a monotonic clock */
@ -701,7 +812,7 @@ _PyTime_Init(void)
return -1;
/* ensure that the operating system provides a monotonic clock */
if (pymonotonic_new(&t, NULL, 1) < 0)
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
return -1;
return 0;
}