Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a47b881

Browse files
committed
Issue #22117: time.time() now uses the new _PyTime_t API
* Add _PyTime_GetSystemClockWithInfo()
1 parent 4bfb460 commit a47b881

3 files changed

Lines changed: 133 additions & 12 deletions

File tree

Include/pytime.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
145145
struct timeval *tv,
146146
_PyTime_round_t round);
147147

148+
/* Get the current time from the system clock.
149+
* Fill clock information if info is not NULL.
150+
* Raise an exception and return -1 on error, return 0 on success.
151+
*/
152+
PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
153+
_PyTime_t *t,
154+
_Py_clock_info_t *info);
155+
148156
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
149157
The clock is not affected by system clock updates. The reference point of
150158
the returned value is undefined, so that only the difference between the

Modules/timemodule.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,12 +1372,14 @@ PyInit_time(void)
13721372
static PyObject*
13731373
floattime(_Py_clock_info_t *info)
13741374
{
1375-
_PyTime_timeval t;
1376-
if (_PyTime_gettimeofday_info(&t, info) < 0) {
1375+
_PyTime_t t;
1376+
double d;
1377+
if (_PyTime_GetSystemClockWithInfo(&t, info) < 0) {
13771378
assert(info != NULL);
13781379
return NULL;
13791380
}
1380-
return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6);
1381+
d = _PyTime_AsSecondsDouble(t);
1382+
return PyFloat_FromDouble(d);
13811383
}
13821384

13831385

Python/pytime.c

Lines changed: 120 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,6 @@ _PyTime_gettimeofday(_PyTime_timeval *tp)
119119
}
120120
}
121121

122-
int
123-
_PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
124-
{
125-
return pygettimeofday(tp, info, 1);
126-
}
127-
128122
static int
129123
pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
130124
{
@@ -414,7 +408,7 @@ _PyTime_FromNanoseconds(PY_LONG_LONG ns)
414408
return t;
415409
}
416410

417-
#if !defined(MS_WINDOWS) && !defined(__APPLE__)
411+
#ifdef HAVE_CLOCK_GETTIME
418412
static int
419413
_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
420414
{
@@ -430,6 +424,23 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts)
430424
*tp = t;
431425
return 0;
432426
}
427+
#else
428+
static int
429+
_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv)
430+
{
431+
_PyTime_t t;
432+
433+
t = (_PyTime_t)tv->tv_sec * SEC_TO_NS;
434+
if (t / SEC_TO_NS != tv->tv_sec) {
435+
_PyTime_overflow();
436+
return -1;
437+
}
438+
439+
t += (_PyTime_t)tv->tv_usec * US_TO_NS;
440+
441+
*tp = t;
442+
return 0;
443+
}
433444
#endif
434445

435446
int
@@ -561,6 +572,102 @@ _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
561572
return 0;
562573
}
563574

575+
static int
576+
pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
577+
{
578+
#ifdef MS_WINDOWS
579+
FILETIME system_time;
580+
ULARGE_INTEGER large;
581+
582+
assert(info == NULL || raise);
583+
584+
GetSystemTimeAsFileTime(&system_time);
585+
large.u.LowPart = system_time.dwLowDateTime;
586+
large.u.HighPart = system_time.dwHighDateTime;
587+
/* 11,644,473,600,000,000,000: number of nanoseconds between
588+
the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
589+
days). */
590+
*tp = large.QuadPart * 100 - 11644473600000000000;
591+
if (info) {
592+
DWORD timeAdjustment, timeIncrement;
593+
BOOL isTimeAdjustmentDisabled, ok;
594+
595+
info->implementation = "GetSystemTimeAsFileTime()";
596+
info->monotonic = 0;
597+
ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
598+
&isTimeAdjustmentDisabled);
599+
if (!ok) {
600+
PyErr_SetFromWindowsErr(0);
601+
return -1;
602+
}
603+
info->resolution = timeIncrement * 1e-7;
604+
info->adjustable = 1;
605+
}
606+
607+
#else /* MS_WINDOWS */
608+
int err;
609+
#ifdef HAVE_CLOCK_GETTIME
610+
struct timespec ts;
611+
#else
612+
struct timeval tv;
613+
#endif
614+
615+
assert(info == NULL || raise);
616+
617+
#ifdef HAVE_CLOCK_GETTIME
618+
err = clock_gettime(CLOCK_REALTIME, &ts);
619+
if (err) {
620+
if (raise)
621+
PyErr_SetFromErrno(PyExc_OSError);
622+
return -1;
623+
}
624+
if (_PyTime_FromTimespec(tp, &ts) < 0)
625+
return -1;
626+
627+
if (info) {
628+
struct timespec res;
629+
info->implementation = "clock_gettime(CLOCK_REALTIME)";
630+
info->monotonic = 0;
631+
info->adjustable = 1;
632+
if (clock_getres(CLOCK_REALTIME, &res) == 0)
633+
info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
634+
else
635+
info->resolution = 1e-9;
636+
}
637+
#else /* HAVE_CLOCK_GETTIME */
638+
639+
/* test gettimeofday() */
640+
#ifdef GETTIMEOFDAY_NO_TZ
641+
err = gettimeofday(&tv);
642+
#else
643+
err = gettimeofday(&tv, (struct timezone *)NULL);
644+
#endif
645+
if (err) {
646+
if (raise)
647+
PyErr_SetFromErrno(PyExc_OSError);
648+
return -1;
649+
}
650+
if (_PyTime_FromTimeval(tp, &tv) < 0)
651+
return -1;
652+
653+
if (info) {
654+
info->implementation = "gettimeofday()";
655+
info->resolution = 1e-6;
656+
info->monotonic = 0;
657+
info->adjustable = 1;
658+
}
659+
#endif /* !HAVE_CLOCK_GETTIME */
660+
#endif /* !MS_WINDOWS */
661+
return 0;
662+
}
663+
664+
int
665+
_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
666+
{
667+
return pygettimeofday_new(t, info, 1);
668+
}
669+
670+
564671
static int
565672
pymonotonic_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
566673
{
@@ -693,15 +800,19 @@ _PyTime_Init(void)
693800
_PyTime_t t;
694801

695802
/* ensure that the system clock works */
696-
if (_PyTime_gettimeofday_info(&tv, NULL) < 0)
803+
if (pygettimeofday(&tv, NULL, 1) < 0)
804+
return -1;
805+
806+
/* ensure that the system clock works */
807+
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
697808
return -1;
698809

699810
/* ensure that the operating system provides a monotonic clock */
700811
if (_PyTime_monotonic_info(&tv, NULL) < 0)
701812
return -1;
702813

703814
/* ensure that the operating system provides a monotonic clock */
704-
if (pymonotonic_new(&t, NULL, 1) < 0)
815+
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
705816
return -1;
706817
return 0;
707818
}

0 commit comments

Comments
 (0)