Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Include/cpython/pytime.h
Line
Count
Source
1
// The _PyTime_t API is written to use timestamp and timeout values stored in
2
// various formats and to read clocks.
3
//
4
// The _PyTime_t type is an integer to support directly common arithmetic
5
// operations like t1 + t2.
6
//
7
// The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type
8
// is signed to support negative timestamps. The supported range is around
9
// [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the
10
// supported date range is around [1677-09-21; 2262-04-11].
11
//
12
// Formats:
13
//
14
// * seconds
15
// * seconds as a floating pointer number (C double)
16
// * milliseconds (10^-3 seconds)
17
// * microseconds (10^-6 seconds)
18
// * 100 nanoseconds (10^-7 seconds)
19
// * nanoseconds (10^-9 seconds)
20
// * timeval structure, 1 microsecond resolution (10^-6 seconds)
21
// * timespec structure, 1 nanosecond resolution (10^-9 seconds)
22
//
23
// Integer overflows are detected and raise OverflowError. Conversion to a
24
// resolution worse than 1 nanosecond is rounded correctly with the requested
25
// rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling
26
// (towards +inf), half even and up (away from zero).
27
//
28
// Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so
29
// the caller doesn't have to handle errors and doesn't need to hold the GIL.
30
// For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on
31
// overflow.
32
//
33
// Clocks:
34
//
35
// * System clock
36
// * Monotonic clock
37
// * Performance counter
38
//
39
// Operations like (t * k / q) with integers are implemented in a way to reduce
40
// the risk of integer overflow. Such operation is used to convert a clock
41
// value expressed in ticks with a frequency to _PyTime_t, like
42
// QueryPerformanceCounter() with QueryPerformanceFrequency().
43
44
#ifndef Py_LIMITED_API
45
#ifndef Py_PYTIME_H
46
#define Py_PYTIME_H
47
48
/**************************************************************************
49
Symbols and macros to supply platform-independent interfaces to time related
50
functions and constants
51
**************************************************************************/
52
#ifdef __cplusplus
53
extern "C" {
54
#endif
55
56
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
57
   store a duration, and so indirectly a date (related to another date, like
58
   UNIX epoch). */
59
typedef int64_t _PyTime_t;
60
// _PyTime_MIN nanoseconds is around -292.3 years
61
#define _PyTime_MIN INT64_MIN
62
// _PyTime_MAX nanoseconds is around +292.3 years
63
#define _PyTime_MAX INT64_MAX
64
#define _SIZEOF_PYTIME_T 8
65
66
typedef enum {
67
    /* Round towards minus infinity (-inf).
68
       For example, used to read a clock. */
69
    _PyTime_ROUND_FLOOR=0,
70
    /* Round towards infinity (+inf).
71
       For example, used for timeout to wait "at least" N seconds. */
72
    _PyTime_ROUND_CEILING=1,
73
    /* Round to nearest with ties going to nearest even integer.
74
       For example, used to round from a Python float. */
75
    _PyTime_ROUND_HALF_EVEN=2,
76
    /* Round away from zero
77
       For example, used for timeout. _PyTime_ROUND_CEILING rounds
78
       -1e-9 to 0 milliseconds which causes bpo-31786 issue.
79
       _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
80
       the timeout sign as expected. select.poll(timeout) must block
81
       for negative values." */
82
    _PyTime_ROUND_UP=3,
83
    /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
84
       used for timeouts. */
85
    _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
86
} _PyTime_round_t;
87
88
89
/* Convert a time_t to a PyLong. */
90
PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
91
    time_t sec);
92
93
/* Convert a PyLong to a time_t. */
94
PyAPI_FUNC(time_t) _PyLong_AsTime_t(
95
    PyObject *obj);
96
97
/* Convert a number of seconds, int or float, to time_t. */
98
PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
99
    PyObject *obj,
100
    time_t *sec,
101
    _PyTime_round_t);
102
103
/* Convert a number of seconds, int or float, to a timeval structure.
104
   usec is in the range [0; 999999] and rounded towards zero.
105
   For example, -1.2 is converted to (-2, 800000). */
106
PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
107
    PyObject *obj,
108
    time_t *sec,
109
    long *usec,
110
    _PyTime_round_t);
111
112
/* Convert a number of seconds, int or float, to a timespec structure.
113
   nsec is in the range [0; 999999999] and rounded towards zero.
114
   For example, -1.2 is converted to (-2, 800000000). */
115
PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
116
    PyObject *obj,
117
    time_t *sec,
118
    long *nsec,
119
    _PyTime_round_t);
120
121
122
/* Create a timestamp from a number of seconds. */
123
PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
124
125
/* Macro to create a timestamp from a number of seconds, no integer overflow.
126
   Only use the macro for small values, prefer _PyTime_FromSeconds(). */
127
#define _PYTIME_FROMSECONDS(seconds) \
128
            ((_PyTime_t)(seconds) * (1000 * 1000 * 1000))
129
130
/* Create a timestamp from a number of nanoseconds. */
131
PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns);
132
133
/* Create a timestamp from a number of microseconds.
134
 * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */
135
PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us);
136
137
/* Create a timestamp from nanoseconds (Python int). */
138
PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t,
139
    PyObject *obj);
140
141
/* Convert a number of seconds (Python float or int) to a timestamp.
142
   Raise an exception and return -1 on error, return 0 on success. */
143
PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
144
    PyObject *obj,
145
    _PyTime_round_t round);
146
147
/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
148
   Raise an exception and return -1 on error, return 0 on success. */
149
PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
150
    PyObject *obj,
151
    _PyTime_round_t round);
152
153
/* Convert a timestamp to a number of seconds as a C double. */
154
PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
155
156
/* Convert timestamp to a number of milliseconds (10^-3 seconds). */
157
PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
158
    _PyTime_round_t round);
159
160
/* Convert timestamp to a number of microseconds (10^-6 seconds). */
161
PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
162
    _PyTime_round_t round);
163
164
/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */
165
PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t);
166
167
#ifdef MS_WINDOWS
168
// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
169
PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t,
170
    _PyTime_round_t round);
171
#endif
172
173
/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
174
   object. */
175
PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
176
177
#ifndef MS_WINDOWS
178
/* Create a timestamp from a timeval structure.
179
   Raise an exception and return -1 on overflow, return 0 on success. */
180
PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv);
181
#endif
182
183
/* Convert a timestamp to a timeval structure (microsecond resolution).
184
   tv_usec is always positive.
185
   Raise an exception and return -1 if the conversion overflowed,
186
   return 0 on success. */
187
PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
188
    struct timeval *tv,
189
    _PyTime_round_t round);
190
191
/* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow.
192
   On overflow, clamp tv_sec to _PyTime_t min/max. */
193
PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t,
194
    struct timeval *tv,
195
    _PyTime_round_t round);
196
197
/* Convert a timestamp to a number of seconds (secs) and microseconds (us).
198
   us is always positive. This function is similar to _PyTime_AsTimeval()
199
   except that secs is always a time_t type, whereas the timeval structure
200
   uses a C long for tv_sec on Windows.
201
   Raise an exception and return -1 if the conversion overflowed,
202
   return 0 on success. */
203
PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
204
    _PyTime_t t,
205
    time_t *secs,
206
    int *us,
207
    _PyTime_round_t round);
208
209
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
210
/* Create a timestamp from a timespec structure.
211
   Raise an exception and return -1 on overflow, return 0 on success. */
212
PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts);
213
214
/* Convert a timestamp to a timespec structure (nanosecond resolution).
215
   tv_nsec is always positive.
216
   Raise an exception and return -1 on error, return 0 on success. */
217
PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
218
219
/* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow.
220
   On overflow, clamp tv_sec to _PyTime_t min/max. */
221
PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts);
222
#endif
223
224
225
// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
226
PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2);
227
228
/* Compute ticks * mul / div.
229
   Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
230
   The caller must ensure that ((div - 1) * mul) cannot overflow. */
231
PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks,
232
    _PyTime_t mul,
233
    _PyTime_t div);
234
235
/* Structure used by time.get_clock_info() */
236
typedef struct {
237
    const char *implementation;
238
    int monotonic;
239
    int adjustable;
240
    double resolution;
241
} _Py_clock_info_t;
242
243
/* Get the current time from the system clock.
244
245
   If the internal clock fails, silently ignore the error and return 0.
246
   On integer overflow, silently ignore the overflow and clamp the clock to
247
   [_PyTime_MIN; _PyTime_MAX].
248
249
   Use _PyTime_GetSystemClockWithInfo() to check for failure. */
250
PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
251
252
/* Get the current time from the system clock.
253
 * On success, set *t and *info (if not NULL), and return 0.
254
 * On error, raise an exception and return -1.
255
 */
256
PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
257
    _PyTime_t *t,
258
    _Py_clock_info_t *info);
259
260
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
261
   The clock is not affected by system clock updates. The reference point of
262
   the returned value is undefined, so that only the difference between the
263
   results of consecutive calls is valid.
264
265
   If the internal clock fails, silently ignore the error and return 0.
266
   On integer overflow, silently ignore the overflow and clamp the clock to
267
   [_PyTime_MIN; _PyTime_MAX].
268
269
   Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */
270
PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
271
272
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
273
   The clock is not affected by system clock updates. The reference point of
274
   the returned value is undefined, so that only the difference between the
275
   results of consecutive calls is valid.
276
277
   Fill info (if set) with information of the function used to get the time.
278
279
   Return 0 on success, raise an exception and return -1 on error. */
280
PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo(
281
    _PyTime_t *t,
282
    _Py_clock_info_t *info);
283
284
285
/* Converts a timestamp to the Gregorian time, using the local time zone.
286
   Return 0 on success, raise an exception and return -1 on error. */
287
PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
288
289
/* Converts a timestamp to the Gregorian time, assuming UTC.
290
   Return 0 on success, raise an exception and return -1 on error. */
291
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
292
293
/* Get the performance counter: clock with the highest available resolution to
294
   measure a short duration.
295
296
   If the internal clock fails, silently ignore the error and return 0.
297
   On integer overflow, silently ignore the overflow and clamp the clock to
298
   [_PyTime_MIN; _PyTime_MAX].
299
300
   Use _PyTime_GetPerfCounterWithInfo() to check for failure. */
301
PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
302
303
/* Get the performance counter: clock with the highest available resolution to
304
   measure a short duration.
305
306
   Fill info (if set) with information of the function used to get the time.
307
308
   Return 0 on success, raise an exception and return -1 on error. */
309
PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
310
    _PyTime_t *t,
311
    _Py_clock_info_t *info);
312
313
314
// Create a deadline.
315
// Pseudo code: _PyTime_GetMonotonicClock() + timeout.
316
PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout);
317
318
// Get remaining time from a deadline.
319
// Pseudo code: deadline - _PyTime_GetMonotonicClock().
320
PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline);
321
322
#ifdef __cplusplus
323
}
324
#endif
325
326
#endif /* Py_PYTIME_H */
327
#endif /* Py_LIMITED_API */