Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:41

0001 // The _PyTime_t API is written to use timestamp and timeout values stored in
0002 // various formats and to read clocks.
0003 //
0004 // The _PyTime_t type is an integer to support directly common arithmetic
0005 // operations like t1 + t2.
0006 //
0007 // The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type
0008 // is signed to support negative timestamps. The supported range is around
0009 // [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the
0010 // supported date range is around [1677-09-21; 2262-04-11].
0011 //
0012 // Formats:
0013 //
0014 // * seconds
0015 // * seconds as a floating pointer number (C double)
0016 // * milliseconds (10^-3 seconds)
0017 // * microseconds (10^-6 seconds)
0018 // * 100 nanoseconds (10^-7 seconds)
0019 // * nanoseconds (10^-9 seconds)
0020 // * timeval structure, 1 microsecond resolution (10^-6 seconds)
0021 // * timespec structure, 1 nanosecond resolution (10^-9 seconds)
0022 //
0023 // Integer overflows are detected and raise OverflowError. Conversion to a
0024 // resolution worse than 1 nanosecond is rounded correctly with the requested
0025 // rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling
0026 // (towards +inf), half even and up (away from zero).
0027 //
0028 // Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so
0029 // the caller doesn't have to handle errors and doesn't need to hold the GIL.
0030 // For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on
0031 // overflow.
0032 //
0033 // Clocks:
0034 //
0035 // * System clock
0036 // * Monotonic clock
0037 // * Performance counter
0038 //
0039 // Operations like (t * k / q) with integers are implemented in a way to reduce
0040 // the risk of integer overflow. Such operation is used to convert a clock
0041 // value expressed in ticks with a frequency to _PyTime_t, like
0042 // QueryPerformanceCounter() with QueryPerformanceFrequency().
0043 
0044 #ifndef Py_LIMITED_API
0045 #ifndef Py_PYTIME_H
0046 #define Py_PYTIME_H
0047 
0048 /**************************************************************************
0049 Symbols and macros to supply platform-independent interfaces to time related
0050 functions and constants
0051 **************************************************************************/
0052 #ifdef __cplusplus
0053 extern "C" {
0054 #endif
0055 
0056 #ifdef __clang__
0057 struct timeval;
0058 #endif
0059 
0060 /* _PyTime_t: Python timestamp with subsecond precision. It can be used to
0061    store a duration, and so indirectly a date (related to another date, like
0062    UNIX epoch). */
0063 typedef int64_t _PyTime_t;
0064 // _PyTime_MIN nanoseconds is around -292.3 years
0065 #define _PyTime_MIN INT64_MIN
0066 // _PyTime_MAX nanoseconds is around +292.3 years
0067 #define _PyTime_MAX INT64_MAX
0068 #define _SIZEOF_PYTIME_T 8
0069 
0070 typedef enum {
0071     /* Round towards minus infinity (-inf).
0072        For example, used to read a clock. */
0073     _PyTime_ROUND_FLOOR=0,
0074     /* Round towards infinity (+inf).
0075        For example, used for timeout to wait "at least" N seconds. */
0076     _PyTime_ROUND_CEILING=1,
0077     /* Round to nearest with ties going to nearest even integer.
0078        For example, used to round from a Python float. */
0079     _PyTime_ROUND_HALF_EVEN=2,
0080     /* Round away from zero
0081        For example, used for timeout. _PyTime_ROUND_CEILING rounds
0082        -1e-9 to 0 milliseconds which causes bpo-31786 issue.
0083        _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
0084        the timeout sign as expected. select.poll(timeout) must block
0085        for negative values." */
0086     _PyTime_ROUND_UP=3,
0087     /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
0088        used for timeouts. */
0089     _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
0090 } _PyTime_round_t;
0091 
0092 
0093 /* Convert a time_t to a PyLong. */
0094 PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
0095     time_t sec);
0096 
0097 /* Convert a PyLong to a time_t. */
0098 PyAPI_FUNC(time_t) _PyLong_AsTime_t(
0099     PyObject *obj);
0100 
0101 /* Convert a number of seconds, int or float, to time_t. */
0102 PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
0103     PyObject *obj,
0104     time_t *sec,
0105     _PyTime_round_t);
0106 
0107 /* Convert a number of seconds, int or float, to a timeval structure.
0108    usec is in the range [0; 999999] and rounded towards zero.
0109    For example, -1.2 is converted to (-2, 800000). */
0110 PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
0111     PyObject *obj,
0112     time_t *sec,
0113     long *usec,
0114     _PyTime_round_t);
0115 
0116 /* Convert a number of seconds, int or float, to a timespec structure.
0117    nsec is in the range [0; 999999999] and rounded towards zero.
0118    For example, -1.2 is converted to (-2, 800000000). */
0119 PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
0120     PyObject *obj,
0121     time_t *sec,
0122     long *nsec,
0123     _PyTime_round_t);
0124 
0125 
0126 /* Create a timestamp from a number of seconds. */
0127 PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
0128 
0129 /* Macro to create a timestamp from a number of seconds, no integer overflow.
0130    Only use the macro for small values, prefer _PyTime_FromSeconds(). */
0131 #define _PYTIME_FROMSECONDS(seconds) \
0132             ((_PyTime_t)(seconds) * (1000 * 1000 * 1000))
0133 
0134 /* Create a timestamp from a number of nanoseconds. */
0135 PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns);
0136 
0137 /* Create a timestamp from a number of microseconds.
0138  * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */
0139 PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us);
0140 
0141 /* Create a timestamp from nanoseconds (Python int). */
0142 PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t,
0143     PyObject *obj);
0144 
0145 /* Convert a number of seconds (Python float or int) to a timestamp.
0146    Raise an exception and return -1 on error, return 0 on success. */
0147 PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
0148     PyObject *obj,
0149     _PyTime_round_t round);
0150 
0151 /* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
0152    Raise an exception and return -1 on error, return 0 on success. */
0153 PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
0154     PyObject *obj,
0155     _PyTime_round_t round);
0156 
0157 /* Convert a timestamp to a number of seconds as a C double. */
0158 PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
0159 
0160 /* Convert timestamp to a number of milliseconds (10^-3 seconds). */
0161 PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
0162     _PyTime_round_t round);
0163 
0164 /* Convert timestamp to a number of microseconds (10^-6 seconds). */
0165 PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
0166     _PyTime_round_t round);
0167 
0168 /* Convert timestamp to a number of nanoseconds (10^-9 seconds). */
0169 PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t);
0170 
0171 #ifdef MS_WINDOWS
0172 // Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
0173 PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t,
0174     _PyTime_round_t round);
0175 #endif
0176 
0177 /* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
0178    object. */
0179 PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
0180 
0181 #ifndef MS_WINDOWS
0182 /* Create a timestamp from a timeval structure.
0183    Raise an exception and return -1 on overflow, return 0 on success. */
0184 PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv);
0185 #endif
0186 
0187 /* Convert a timestamp to a timeval structure (microsecond resolution).
0188    tv_usec is always positive.
0189    Raise an exception and return -1 if the conversion overflowed,
0190    return 0 on success. */
0191 PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
0192     struct timeval *tv,
0193     _PyTime_round_t round);
0194 
0195 /* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow.
0196    On overflow, clamp tv_sec to _PyTime_t min/max. */
0197 PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t,
0198     struct timeval *tv,
0199     _PyTime_round_t round);
0200 
0201 /* Convert a timestamp to a number of seconds (secs) and microseconds (us).
0202    us is always positive. This function is similar to _PyTime_AsTimeval()
0203    except that secs is always a time_t type, whereas the timeval structure
0204    uses a C long for tv_sec on Windows.
0205    Raise an exception and return -1 if the conversion overflowed,
0206    return 0 on success. */
0207 PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
0208     _PyTime_t t,
0209     time_t *secs,
0210     int *us,
0211     _PyTime_round_t round);
0212 
0213 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
0214 /* Create a timestamp from a timespec structure.
0215    Raise an exception and return -1 on overflow, return 0 on success. */
0216 PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts);
0217 
0218 /* Convert a timestamp to a timespec structure (nanosecond resolution).
0219    tv_nsec is always positive.
0220    Raise an exception and return -1 on error, return 0 on success. */
0221 PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
0222 
0223 /* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow.
0224    On overflow, clamp tv_sec to _PyTime_t min/max. */
0225 PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts);
0226 #endif
0227 
0228 
0229 // Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
0230 PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2);
0231 
0232 /* Compute ticks * mul / div.
0233    Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
0234    The caller must ensure that ((div - 1) * mul) cannot overflow. */
0235 PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks,
0236     _PyTime_t mul,
0237     _PyTime_t div);
0238 
0239 /* Structure used by time.get_clock_info() */
0240 typedef struct {
0241     const char *implementation;
0242     int monotonic;
0243     int adjustable;
0244     double resolution;
0245 } _Py_clock_info_t;
0246 
0247 /* Get the current time from the system clock.
0248 
0249    If the internal clock fails, silently ignore the error and return 0.
0250    On integer overflow, silently ignore the overflow and clamp the clock to
0251    [_PyTime_MIN; _PyTime_MAX].
0252 
0253    Use _PyTime_GetSystemClockWithInfo() to check for failure. */
0254 PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
0255 
0256 /* Get the current time from the system clock.
0257  * On success, set *t and *info (if not NULL), and return 0.
0258  * On error, raise an exception and return -1.
0259  */
0260 PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
0261     _PyTime_t *t,
0262     _Py_clock_info_t *info);
0263 
0264 /* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
0265    The clock is not affected by system clock updates. The reference point of
0266    the returned value is undefined, so that only the difference between the
0267    results of consecutive calls is valid.
0268 
0269    If the internal clock fails, silently ignore the error and return 0.
0270    On integer overflow, silently ignore the overflow and clamp the clock to
0271    [_PyTime_MIN; _PyTime_MAX].
0272 
0273    Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */
0274 PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
0275 
0276 /* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
0277    The clock is not affected by system clock updates. The reference point of
0278    the returned value is undefined, so that only the difference between the
0279    results of consecutive calls is valid.
0280 
0281    Fill info (if set) with information of the function used to get the time.
0282 
0283    Return 0 on success, raise an exception and return -1 on error. */
0284 PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo(
0285     _PyTime_t *t,
0286     _Py_clock_info_t *info);
0287 
0288 
0289 /* Converts a timestamp to the Gregorian time, using the local time zone.
0290    Return 0 on success, raise an exception and return -1 on error. */
0291 PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
0292 
0293 /* Converts a timestamp to the Gregorian time, assuming UTC.
0294    Return 0 on success, raise an exception and return -1 on error. */
0295 PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
0296 
0297 /* Get the performance counter: clock with the highest available resolution to
0298    measure a short duration.
0299 
0300    If the internal clock fails, silently ignore the error and return 0.
0301    On integer overflow, silently ignore the overflow and clamp the clock to
0302    [_PyTime_MIN; _PyTime_MAX].
0303 
0304    Use _PyTime_GetPerfCounterWithInfo() to check for failure. */
0305 PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
0306 
0307 /* Get the performance counter: clock with the highest available resolution to
0308    measure a short duration.
0309 
0310    Fill info (if set) with information of the function used to get the time.
0311 
0312    Return 0 on success, raise an exception and return -1 on error. */
0313 PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
0314     _PyTime_t *t,
0315     _Py_clock_info_t *info);
0316 
0317 
0318 // Create a deadline.
0319 // Pseudo code: _PyTime_GetMonotonicClock() + timeout.
0320 PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout);
0321 
0322 // Get remaining time from a deadline.
0323 // Pseudo code: deadline - _PyTime_GetMonotonicClock().
0324 PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline);
0325 
0326 #ifdef __cplusplus
0327 }
0328 #endif
0329 
0330 #endif /* Py_PYTIME_H */
0331 #endif /* Py_LIMITED_API */