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/**************************************************************************
49Symbols and macros to supply platform-independent interfaces to time related
50functions and constants
51**************************************************************************/
52#ifdef __cplusplus
53extern "C" {
54#endif
55
56#ifdef __clang__
57struct 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). */
63typedef 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
70typedef 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. */
94PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
95 time_t sec);
96
97/* Convert a PyLong to a time_t. */
98PyAPI_FUNC(time_t) _PyLong_AsTime_t(
99 PyObject *obj);
100
101/* Convert a number of seconds, int or float, to time_t. */
102PyAPI_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). */
110PyAPI_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). */
119PyAPI_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. */
127PyAPI_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. */
135PyAPI_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. */
139PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us);
140
141/* Create a timestamp from nanoseconds (Python int). */
142PyAPI_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. */
147PyAPI_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. */
153PyAPI_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. */
158PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
159
160/* Convert timestamp to a number of milliseconds (10^-3 seconds). */
161PyAPI_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). */
165PyAPI_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). */
169PyAPI_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).
173PyAPI_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. */
179PyAPI_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. */
184PyAPI_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. */
191PyAPI_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. */
197PyAPI_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. */
207PyAPI_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. */
216PyAPI_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. */
221PyAPI_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. */
225PyAPI_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.
230PyAPI_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. */
235PyAPI_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() */
240typedef 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. */
254PyAPI_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 */
260PyAPI_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. */
274PyAPI_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. */
284PyAPI_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. */
291PyAPI_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. */
295PyAPI_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. */
305PyAPI_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. */
313PyAPI_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.
320PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout);
321
322// Get remaining time from a deadline.
323// Pseudo code: deadline - _PyTime_GetMonotonicClock().
324PyAPI_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 */
332

source code of include/python3.12/cpython/pytime.h