From 6fc4ade2bb44a176555703ebc2dbfb54b57e1148 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Thu, 5 Aug 2010 17:34:27 +0000 Subject: Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API exposed in Python.h. This function is similar to POSIX gettimeofday(struct timeval *tp), but available on platforms without gettimeofday(). --- Include/Python.h | 1 + Include/pytime.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile.pre.in | 2 ++ Modules/_datetimemodule.c | 33 ++-------------------- Modules/timemodule.c | 59 +++------------------------------------ PCbuild/pythoncore.vcproj | 8 ++++++ Python/pythonrun.c | 2 ++ Python/pytime.c | 60 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 150 insertions(+), 85 deletions(-) create mode 100644 Include/pytime.h create mode 100644 Python/pytime.c diff --git a/Include/Python.h b/Include/Python.h index 972beec..6fbc49c 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -61,6 +61,7 @@ #error "PYMALLOC_DEBUG requires WITH_PYMALLOC" #endif #include "pymath.h" +#include "pytime.h" #include "pymem.h" #include "object.h" diff --git a/Include/pytime.h b/Include/pytime.h new file mode 100644 index 0000000..53dd37a --- /dev/null +++ b/Include/pytime.h @@ -0,0 +1,70 @@ +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +#include "pyconfig.h" /* include for defines */ + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_GETTIMEOFDAY +typedef struct timeval _PyTime_timeval; +#else +typedef struct { + time_t tv_sec; /* seconds since Jan. 1, 1970 */ + long tv_usec; /* and microseconds */ +} _PyTime_timeval; +#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); + +/* Dummy to force linking. */ +PyAPI_FUNC(void) _PyTime_Init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +#include "pyconfig.h" /* include for defines */ + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_GETTIMEOFDAY +typedef struct timeval _PyTime_timeval; +#else +typedef struct { + time_t tv_sec; /* seconds since Jan. 1, 1970 */ + long tv_usec; /* and microseconds */ +} _PyTime_timeval; +#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); + +/* Dummy to force linking. */ +PyAPI_FUNC(void) _PyTime_Init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 03195a2..279e8d7 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -314,6 +314,7 @@ PYTHON_OBJS= \ Python/pymath.o \ Python/pystate.o \ Python/pythonrun.o \ + Python/pytime.o \ Python/structmember.o \ Python/symtable.o \ Python/sysmodule.o \ @@ -696,6 +697,7 @@ PYTHON_HEADERS= \ Include/pystrtod.h \ Include/pythonrun.h \ Include/pythread.h \ + Include/pytime.h \ Include/rangeobject.h \ Include/setobject.h \ Include/sliceobject.h \ diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index b2505d1..192b1ea 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -8,7 +8,7 @@ #include -#include "timefuncs.h" +#include "_time.h" /* Differentiate between building the core module and building extension * modules. @@ -4166,37 +4166,10 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp, static PyObject * datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) { -#ifdef HAVE_GETTIMEOFDAY - struct timeval t; - -#ifdef GETTIMEOFDAY_NO_TZ - gettimeofday(&t); -#else - gettimeofday(&t, (struct timezone *)NULL); -#endif + _PyTime_timeval t; + _PyTime_gettimeofday(&t); return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec, tzinfo); - -#else /* ! HAVE_GETTIMEOFDAY */ - /* No flavor of gettimeofday exists on this platform. Python's - * time.time() does a lot of other platform tricks to get the - * best time it can on the platform, and we're not going to do - * better than that (if we could, the better code would belong - * in time.time()!) We're limited by the precision of a double, - * though. - */ - PyObject *time; - double dtime; - - time = time_time(); - if (time == NULL) - return NULL; - dtime = PyFloat_AsDouble(time); - Py_DECREF(time); - if (dtime == -1.0 && PyErr_Occurred()) - return NULL; - return datetime_from_timestamp(cls, f, dtime, tzinfo); -#endif /* ! HAVE_GETTIMEOFDAY */ } /* Return best possible local time -- this isn't constrained by the diff --git a/Modules/timemodule.c b/Modules/timemodule.c index c4b5014..879e686 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -3,22 +3,10 @@ #include "Python.h" #include "structseq.h" -#include "timefuncs.h" +#include "_time.h" #define TZNAME_ENCODING "utf-8" -#ifdef __APPLE__ -#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) - /* - * floattime falls back to ftime when getttimeofday fails because the latter - * might fail on some platforms. This fallback is unwanted on MacOSX because - * that makes it impossible to use a binary build on OSX 10.4 on earlier - * releases of the OS. Therefore claim we don't support ftime. - */ -# undef HAVE_FTIME -#endif -#endif - #include #ifdef HAVE_SYS_TYPES_H @@ -29,13 +17,6 @@ #include #endif -#ifdef HAVE_FTIME -#include -#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) -extern int ftime(struct timeb *); -#endif /* MS_WINDOWS */ -#endif /* HAVE_FTIME */ - #if defined(__WATCOMC__) && !defined(__QNX__) #include #else @@ -946,44 +927,12 @@ PyInit_time(void) return m; } - -/* Implement floattime() for various platforms */ - static double floattime(void) { - /* There are three ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds - In all cases the return value is a float in seconds. - 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! */ -#ifdef HAVE_GETTIMEOFDAY - { - struct timeval t; -#ifdef GETTIMEOFDAY_NO_TZ - if (gettimeofday(&t) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; -#else /* !GETTIMEOFDAY_NO_TZ */ - if (gettimeofday(&t, (struct timezone *)NULL) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; -#endif /* !GETTIMEOFDAY_NO_TZ */ - } - -#endif /* !HAVE_GETTIMEOFDAY */ - { -#if defined(HAVE_FTIME) - struct timeb t; - ftime(&t); - return (double)t.time + (double)t.millitm * (double)0.001; -#else /* !HAVE_FTIME */ - time_t secs; - time(&secs); - return (double)secs; -#endif /* !HAVE_FTIME */ - } + _PyTime_timeval t; + _PyTime_gettimeofday(&t); + return (double)t.tv_sec + t.tv_usec*0.000001; } diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj index ad0afd3..9f6a1c8 100644 --- a/PCbuild/pythoncore.vcproj +++ b/PCbuild/pythoncore.vcproj @@ -876,6 +876,10 @@ > + + @@ -1768,6 +1772,10 @@ > + + diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f45d7dc..79a19f8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -268,6 +268,8 @@ Py_InitializeEx(int install_sigs) /* Initialize _warnings. */ _PyWarnings_Init(); + _PyTime_Init(); + initfsencoding(); if (install_sigs) diff --git a/Python/pytime.c b/Python/pytime.c new file mode 100644 index 0000000..6fb7695 --- /dev/null +++ b/Python/pytime.c @@ -0,0 +1,60 @@ +#include "Python.h" + +#ifdef __APPLE__ +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) + /* + * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter + * might fail on some platforms. This fallback is unwanted on MacOSX because + * that makes it impossible to use a binary build on OSX 10.4 on earlier + * releases of the OS. Therefore claim we don't support ftime. + */ +# undef HAVE_FTIME +#endif +#endif + +#ifdef HAVE_FTIME +#include +#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) +extern int ftime(struct timeb *); +#endif /* MS_WINDOWS */ +#endif /* HAVE_FTIME */ + +void +_PyTime_gettimeofday(_PyTime_timeval *tp) +{ + /* There are three ways to get the time: + (1) gettimeofday() -- resolution in microseconds + (2) ftime() -- resolution in milliseconds + (3) time() -- resolution in seconds + In all cases the return value in a timeval struct. + 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! */ +#ifdef HAVE_GETTIMEOFDAY +#ifdef GETTIMEOFDAY_NO_TZ + if (gettimeofday(tp) == 0) + return; +#else /* !GETTIMEOFDAY_NO_TZ */ + if (gettimeofday(tp, (struct timezone *)NULL) == 0) + 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; + } +#else /* !HAVE_FTIME */ + tp->tv_sec = time(NULL); + tp->tv_usec = 0; +#endif /* !HAVE_FTIME */ + return; +} + +void +_PyTime_Init() +{ + /* Do nothing. Needed to force linking. */ +} -- cgit v0.12