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 #ifdef __clang__
57 struct timeval;
58 #endif
59
60 /* _PyTime_t: Python timestamp with subsecond precision. It can be used to
61 store a duration, and so indirectly a date (related to another date, like
62 UNIX epoch). */
63 typedef int64_t _PyTime_t;
64 // _PyTime_MIN nanoseconds is around -292.3 years
65 #define _PyTime_MIN INT64_MIN
66 // _PyTime_MAX nanoseconds is around +292.3 years
67 #define _PyTime_MAX INT64_MAX
68 #define _SIZEOF_PYTIME_T 8
69
70 typedef enum {
71 /* Round towards minus infinity (-inf).
72 For example, used to read a clock. */
73 _PyTime_ROUND_FLOOR=0,
74 /* Round towards infinity (+inf).
75 For example, used for timeout to wait "at least" N seconds. */
76 _PyTime_ROUND_CEILING=1,
77 /* Round to nearest with ties going to nearest even integer.
78 For example, used to round from a Python float. */
79 _PyTime_ROUND_HALF_EVEN=2,
80 /* Round away from zero
81 For example, used for timeout. _PyTime_ROUND_CEILING rounds
82 -1e-9 to 0 milliseconds which causes bpo-31786 issue.
83 _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
84 the timeout sign as expected. select.poll(timeout) must block
85 for negative values." */
86 _PyTime_ROUND_UP=3,
87 /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
88 used for timeouts. */
89 _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
90 } _PyTime_round_t;
91
92
93 /* Convert a time_t to a PyLong. */
94 PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
95 time_t sec);
96
97 /* Convert a PyLong to a time_t. */
98 PyAPI_FUNC(time_t) _PyLong_AsTime_t(
99 PyObject *obj);
100
101 /* Convert a number of seconds, int or float, to time_t. */
102 PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
103 PyObject *obj,
104 time_t *sec,
105 _PyTime_round_t);
106
107 /* Convert a number of seconds, int or float, to a timeval structure.
108 usec is in the range [0; 999999] and rounded towards zero.
109 For example, -1.2 is converted to (-2, 800000). */
110 PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
111 PyObject *obj,
112 time_t *sec,
113 long *usec,
114 _PyTime_round_t);
115
116 /* Convert a number of seconds, int or float, to a timespec structure.
117 nsec is in the range [0; 999999999] and rounded towards zero.
118 For example, -1.2 is converted to (-2, 800000000). */
119 PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
120 PyObject *obj,
121 time_t *sec,
122 long *nsec,
123 _PyTime_round_t);
124
125
126 /* Create a timestamp from a number of seconds. */
127 PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
128
129 /* Macro to create a timestamp from a number of seconds, no integer overflow.
130 Only use the macro for small values, prefer _PyTime_FromSeconds(). */
131 #define _PYTIME_FROMSECONDS(seconds) \
132 ((_PyTime_t)(seconds) * (1000 * 1000 * 1000))
133
134 /* Create a timestamp from a number of nanoseconds. */
135 PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns);
136
137 /* Create a timestamp from a number of microseconds.
138 * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */
139 PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us);
140
141 /* Create a timestamp from nanoseconds (Python int). */
142 PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t,
143 PyObject *obj);
144
145 /* Convert a number of seconds (Python float or int) to a timestamp.
146 Raise an exception and return -1 on error, return 0 on success. */
147 PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
148 PyObject *obj,
149 _PyTime_round_t round);
150
151 /* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
152 Raise an exception and return -1 on error, return 0 on success. */
153 PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
154 PyObject *obj,
155 _PyTime_round_t round);
156
157 /* Convert a timestamp to a number of seconds as a C double. */
158 PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
159
160 /* Convert timestamp to a number of milliseconds (10^-3 seconds). */
161 PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
162 _PyTime_round_t round);
163
164 /* Convert timestamp to a number of microseconds (10^-6 seconds). */
165 PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
166 _PyTime_round_t round);
167
168 /* Convert timestamp to a number of nanoseconds (10^-9 seconds). */
169 PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t);
170
171 #ifdef MS_WINDOWS
172 // Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
173 PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t,
174 _PyTime_round_t round);
175 #endif
176
177 /* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
178 object. */
179 PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
180
181 #ifndef MS_WINDOWS
182 /* Create a timestamp from a timeval structure.
183 Raise an exception and return -1 on overflow, return 0 on success. */
184 PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv);
185 #endif
186
187 /* Convert a timestamp to a timeval structure (microsecond resolution).
188 tv_usec is always positive.
189 Raise an exception and return -1 if the conversion overflowed,
190 return 0 on success. */
191 PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
192 struct timeval *tv,
193 _PyTime_round_t round);
194
195 /* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow.
196 On overflow, clamp tv_sec to _PyTime_t min/max. */
197 PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t,
198 struct timeval *tv,
199 _PyTime_round_t round);
200
201 /* Convert a timestamp to a number of seconds (secs) and microseconds (us).
202 us is always positive. This function is similar to _PyTime_AsTimeval()
203 except that secs is always a time_t type, whereas the timeval structure
204 uses a C long for tv_sec on Windows.
205 Raise an exception and return -1 if the conversion overflowed,
206 return 0 on success. */
207 PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
208 _PyTime_t t,
209 time_t *secs,
210 int *us,
211 _PyTime_round_t round);
212
213 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
214 /* Create a timestamp from a timespec structure.
215 Raise an exception and return -1 on overflow, return 0 on success. */
216 PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts);
217
218 /* Convert a timestamp to a timespec structure (nanosecond resolution).
219 tv_nsec is always positive.
220 Raise an exception and return -1 on error, return 0 on success. */
221 PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
222
223 /* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow.
224 On overflow, clamp tv_sec to _PyTime_t min/max. */
225 PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts);
226 #endif
227
228
229 // Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
230 PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2);
231
232 /* Compute ticks * mul / div.
233 Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
234 The caller must ensure that ((div - 1) * mul) cannot overflow. */
235 PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks,
236 _PyTime_t mul,
237 _PyTime_t div);
238
239 /* Structure used by time.get_clock_info() */
240 typedef struct {
241 const char *implementation;
242 int monotonic;
243 int adjustable;
244 double resolution;
245 } _Py_clock_info_t;
246
247 /* Get the current time from the system clock.
248
249 If the internal clock fails, silently ignore the error and return 0.
250 On integer overflow, silently ignore the overflow and clamp the clock to
251 [_PyTime_MIN; _PyTime_MAX].
252
253 Use _PyTime_GetSystemClockWithInfo() to check for failure. */
254 PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
255
256 /* Get the current time from the system clock.
257 * On success, set *t and *info (if not NULL), and return 0.
258 * On error, raise an exception and return -1.
259 */
260 PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
261 _PyTime_t *t,
262 _Py_clock_info_t *info);
263
264 /* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
265 The clock is not affected by system clock updates. The reference point of
266 the returned value is undefined, so that only the difference between the
267 results of consecutive calls is valid.
268
269 If the internal clock fails, silently ignore the error and return 0.
270 On integer overflow, silently ignore the overflow and clamp the clock to
271 [_PyTime_MIN; _PyTime_MAX].
272
273 Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */
274 PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
275
276 /* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
277 The clock is not affected by system clock updates. The reference point of
278 the returned value is undefined, so that only the difference between the
279 results of consecutive calls is valid.
280
281 Fill info (if set) with information of the function used to get the time.
282
283 Return 0 on success, raise an exception and return -1 on error. */
284 PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo(
285 _PyTime_t *t,
286 _Py_clock_info_t *info);
287
288
289 /* Converts a timestamp to the Gregorian time, using the local time zone.
290 Return 0 on success, raise an exception and return -1 on error. */
291 PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
292
293 /* Converts a timestamp to the Gregorian time, assuming UTC.
294 Return 0 on success, raise an exception and return -1 on error. */
295 PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
296
297 /* Get the performance counter: clock with the highest available resolution to
298 measure a short duration.
299
300 If the internal clock fails, silently ignore the error and return 0.
301 On integer overflow, silently ignore the overflow and clamp the clock to
302 [_PyTime_MIN; _PyTime_MAX].
303
304 Use _PyTime_GetPerfCounterWithInfo() to check for failure. */
305 PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
306
307 /* Get the performance counter: clock with the highest available resolution to
308 measure a short duration.
309
310 Fill info (if set) with information of the function used to get the time.
311
312 Return 0 on success, raise an exception and return -1 on error. */
313 PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
314 _PyTime_t *t,
315 _Py_clock_info_t *info);
316
317
318 // Create a deadline.
319 // Pseudo code: _PyTime_GetMonotonicClock() + timeout.
320 PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout);
321
322 // Get remaining time from a deadline.
323 // Pseudo code: deadline - _PyTime_GetMonotonicClock().
324 PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline);
325
326 #ifdef __cplusplus
327 }
328 #endif
329
330 #endif /* Py_PYTIME_H */
331 #endif /* Py_LIMITED_API */