diff --git a/Include/pytime.h b/Include/pytime.h --- a/Include/pytime.h +++ b/Include/pytime.h @@ -12,30 +12,30 @@ functions and constants extern "C" { #endif -#ifdef HAVE_GETTIMEOFDAY -typedef struct timeval _PyTime_timeval; +#ifdef HAVE_CLOCK_GETTIME +typedef struct timespec _PyTime_timespec; #else typedef struct { time_t tv_sec; /* seconds since Jan. 1, 1970 */ - long tv_usec; /* and microseconds */ -} _PyTime_timeval; + long tv_nsec; /* and nanoseconds (10^-9) */ +} _PyTime_timespec; #endif /* Similar to POSIX gettimeofday but cannot fail. If system gettimeofday * fails or is not available, fall back to lower resolution clocks. */ -PyAPI_FUNC(void) _PyTime_gettimeofday(_PyTime_timeval *tp); +PyAPI_FUNC(void) _PyTime_gettimeofday(_PyTime_timespec *tp); #define _PyTime_ADD_SECONDS(tv, interval) \ do { \ - tv.tv_usec += (long) (((long) interval - interval) * 1000000); \ - tv.tv_sec += (time_t) interval + (time_t) (tv.tv_usec / 1000000); \ - tv.tv_usec %= 1000000; \ + tv.tv_nsec += (long) (((long) interval - interval) * 1000000000); \ + tv.tv_sec += (time_t) interval + (time_t) (tv.tv_nsec / 1000000000); \ + tv.tv_nsec %= 1000000000; \ } while (0) #define _PyTime_INTERVAL(tv_start, tv_end) \ ((tv_end.tv_sec - tv_start.tv_sec) + \ - (tv_end.tv_usec - tv_start.tv_usec) * 0.000001) + (tv_end.tv_nsec - tv_start.tv_nsec) * 1e-9) /* Dummy to force linking. */ PyAPI_FUNC(void) _PyTime_Init(void); diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -4131,9 +4131,10 @@ datetime_from_timestamp(PyObject *cls, T static PyObject * datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) { - _PyTime_timeval t; + _PyTime_timespec t; _PyTime_gettimeofday(&t); - return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec, + return datetime_from_timet_and_us(cls, f, + t.tv_sec, (int)(t.tv_nsec / 1000), tzinfo); } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -50,14 +50,13 @@ static PyLockStatus acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) { PyLockStatus r; - _PyTime_timeval curtime; - _PyTime_timeval endtime; + _PyTime_timespec curtime, endtime; if (microseconds > 0) { _PyTime_gettimeofday(&endtime); endtime.tv_sec += microseconds / (1000 * 1000); - endtime.tv_usec += microseconds % (1000 * 1000); + endtime.tv_nsec += (microseconds % (1000 * 1000)) * 1000; } @@ -79,7 +78,7 @@ acquire_timed(PyThread_type_lock lock, P if (microseconds > 0) { _PyTime_gettimeofday(&curtime); microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 + - (endtime.tv_usec - curtime.tv_usec)); + (endtime.tv_nsec - curtime.tv_nsec) / 1000); /* Check for negative values, since those mean block forever. */ diff --git a/Modules/timemodule.c b/Modules/timemodule.c --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -78,9 +78,8 @@ time_clock(PyObject *self, PyObject *unu QueryPerformanceCounter(&ctrStart); if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { /* Unlikely to happen - this works on all intel - machines at least! Revert to clock() */ - return PyFloat_FromDouble(((double)clock()) / - CLOCKS_PER_SEC); + machines at least! */ + return time_time(NULL, NULL); } divisor = (double)freq.QuadPart; } @@ -741,7 +740,7 @@ static PyObject * time_wallclock(PyObject *self, PyObject *unused) { #if defined(MS_WINDOWS) && !defined(__BORLANDC__) - return time_clock(self, NULL); + return time_clock(NULL, NULL); #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) static int clk_index = 0; clockid_t clk_ids[] = { @@ -1006,9 +1005,9 @@ PyInit_time(void) static double floattime(void) { - _PyTime_timeval t; + _PyTime_timespec t; _PyTime_gettimeofday(&t); - return (double)t.tv_sec + t.tv_usec*0.000001; + return (double)t.tv_sec + t.tv_nsec * 1e-9; } diff --git a/Python/pytime.c b/Python/pytime.c --- a/Python/pytime.c +++ b/Python/pytime.c @@ -20,8 +20,20 @@ extern int ftime(struct timeb *); #endif /* HAVE_FTIME */ void -_PyTime_gettimeofday(_PyTime_timeval *tp) +_PyTime_gettimeofday(_PyTime_timespec *tp) { +#ifdef MS_WINDOWS + FILETIME system_time; + ULARGE_INTEGER large; + ULONGLONG seconds; + double t; + + GetSystemTimeAsFileTime(&system_time); + large.u.LowPart = system_time.dwLowDateTime; + large.u.HighPart = system_time..dwHighDateTime; + tp->tv_sec = large.QuadPart / 10000000; + tp->tv_nsec = (large.QuadPart % 10000000) * 100; +#else /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds (2) ftime() -- resolution in milliseconds @@ -30,27 +42,38 @@ _PyTime_gettimeofday(_PyTime_timeval *tp Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may fail, so we fall back on ftime() or time(). Note: clock resolution does not imply clock accuracy! */ +#if defined(HAVE_FTIME) + struct timeb t; +#endif + #ifdef HAVE_GETTIMEOFDAY + struct timeval tv; #ifdef GETTIMEOFDAY_NO_TZ - if (gettimeofday(tp) == 0) + if (gettimeofday(&tv) == 0) + { + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; return; + } #else /* !GETTIMEOFDAY_NO_TZ */ - if (gettimeofday(tp, (struct timezone *)NULL) == 0) + if (gettimeofday(&tv, (struct timezone *)NULL) == 0) + { + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; return; + } #endif /* !GETTIMEOFDAY_NO_TZ */ #endif /* !HAVE_GETTIMEOFDAY */ + #if defined(HAVE_FTIME) - { - struct timeb t; - ftime(&t); - tp->tv_sec = t.time; - tp->tv_usec = t.millitm * 1000; - } + ftime(&t); + tp->tv_sec = t.time; + tp->tv_nsec = t.millitm * 1000000; #else /* !HAVE_FTIME */ tp->tv_sec = time(NULL); - tp->tv_usec = 0; + tp->tv_nsec = 0; #endif /* !HAVE_FTIME */ - return; +#endif } void