Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit879f454

Browse files
encukouvstinner
andauthored
gh-110850: Add PyTime_t C API (GH-115215)
*gh-110850: Add PyTime_t C APIAdd PyTime_t API:* PyTime_t type.* PyTime_MIN and PyTime_MAX constants.* PyTime_AsSecondsDouble(), PyTime_Monotonic(), PyTime_PerfCounter() and PyTime_GetSystemClock() functions.Co-authored-by: Victor Stinner <vstinner@python.org>
1 parentc39272e commit879f454

File tree

19 files changed

+448
-114
lines changed

19 files changed

+448
-114
lines changed

‎Doc/c-api/time.rst

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
..highlight::c
2+
3+
PyTime C API
4+
============
5+
6+
..versionadded::3.13
7+
8+
The clock C API provides access to system clocks.
9+
It is similar to the Python:mod:`time` module.
10+
11+
For C API related to the:mod:`datetime` module, see:ref:`datetimeobjects`.
12+
13+
14+
Types
15+
-----
16+
17+
..c:type:: PyTime_t
18+
19+
A timestamp or duration in nanoseconds, represented as a signed 64-bit
20+
integer.
21+
22+
The reference point for timestamps depends on the clock used. For example,
23+
:c:func:`PyTime_Time` returns timestamps relative to the UNIX epoch.
24+
25+
The supported range is around [-292.3 years; +292.3 years].
26+
Using the Unix epoch (January 1st, 1970) as reference, the supported date
27+
range is around [1677-09-21; 2262-04-11].
28+
The exact limits are exposed as constants:
29+
30+
..c:var:: PyTime_t PyTime_MIN
31+
32+
Minimum value of:c:type:`PyTime_t`.
33+
34+
..c:var:: PyTime_t PyTime_MAX
35+
36+
Maximum value of:c:type:`PyTime_t`.
37+
38+
39+
Clock Functions
40+
---------------
41+
42+
The following functions take a pointer to a:c:expr:`PyTime_t` that they
43+
set to the value of a particular clock.
44+
Details of each clock are given in the documentation of the corresponding
45+
Python function.
46+
47+
The functions return ``0`` on success, or ``-1`` (with an exception set)
48+
on failure.
49+
50+
On integer overflow, they set the:c:data:`PyExc_OverflowError` exception and
51+
set ``*result`` to the value clamped to the ``[PyTime_MIN; PyTime_MAX]``
52+
range.
53+
(On current systems, integer overflows are likely caused by misconfigured
54+
system time.)
55+
56+
As any other C API (unless otherwise specified), the functions must be called
57+
with the:term:`GIL` held.
58+
59+
..c:function::intPyTime_Monotonic(PyTime_t *result)
60+
61+
Read the monotonic clock.
62+
See:func:`time.monotonic` for important details on this clock.
63+
64+
..c:function::intPyTime_PerfCounter(PyTime_t *result)
65+
66+
Read the performance counter.
67+
See:func:`time.perf_counter` for important details on this clock.
68+
69+
..c:function::intPyTime_Time(PyTime_t *result)
70+
71+
Read the “wall clock” time.
72+
See:func:`time.time` for details important on this clock.
73+
74+
75+
Conversion functions
76+
--------------------
77+
78+
..c:function::doublePyTime_AsSecondsDouble(PyTime_t t)
79+
80+
Convert a timestamp to a number of seconds as a C :c:expr:`double`.
81+
82+
The function cannot fail, but note that :c:expr:`double` has limited
83+
accuracy for large values.

‎Doc/c-api/utilities.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ and parsing function arguments and constructing Python values from C values.
2020
hash.rst
2121
reflection.rst
2222
codec.rst
23+
time.rst
2324
perfmaps.rst

‎Doc/conf.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,14 @@
135135
('c:type','wchar_t'),
136136
('c:type','__int64'),
137137
('c:type','unsigned __int64'),
138+
('c:type','double'),
138139
# Standard C structures
139140
('c:struct','in6_addr'),
140141
('c:struct','in_addr'),
141142
('c:struct','stat'),
142143
('c:struct','statvfs'),
144+
('c:struct','timeval'),
145+
('c:struct','timespec'),
143146
# Standard C macros
144147
('c:macro','LLONG_MAX'),
145148
('c:macro','LLONG_MIN'),
@@ -269,12 +272,12 @@
269272
('py:meth','index'),# list.index, tuple.index, etc.
270273
]
271274

272-
# gh-106948: Copy standard C types declared in the "c:type" domainto the
273-
# "c:identifier" domain, since"c:function" markup looks for types in the
274-
# "c:identifier" domain. Use list() to not iterate on items which are being
275-
# added
275+
# gh-106948: Copy standard C types declared in the "c:type" domainand C
276+
#structures declared in the"c:struct" domain to the"c:identifier" domain,
277+
#since"c:function" markup looks for types in the "c:identifier" domain. Use
278+
#list() to not iterate on items which are beingadded
276279
forrole,nameinlist(nitpick_ignore):
277-
ifrole=='c:type':
280+
ifrolein ('c:type','c:struct'):
278281
nitpick_ignore.append(('c:identifier',name))
279282
delrole,name
280283

‎Doc/whatsnew/3.13.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,16 @@ New Features
15161516
* Add:c:func:`Py_HashPointer` function to hash a pointer.
15171517
(Contributed by Victor Stinner in:gh:`111545`.)
15181518

1519+
* Add PyTime C API:
1520+
1521+
*:c:type:`PyTime_t` type.
1522+
*:c:var:`PyTime_MIN` and:c:var:`PyTime_MAX` constants.
1523+
*:c:func:`PyTime_AsSecondsDouble`
1524+
:c:func:`PyTime_Monotonic`,:c:func:`PyTime_PerfCounter`, and
1525+
:c:func:`PyTime_Time` functions.
1526+
1527+
(Contributed by Victor Stinner and Petr Viktorin in:gh:`110850`.)
1528+
15191529

15201530
Porting to Python 3.13
15211531
----------------------

‎Include/Python.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
#include"weakrefobject.h"
9898
#include"structseq.h"
9999
#include"cpython/picklebufobject.h"
100+
#include"cpython/pytime.h"
100101
#include"codecs.h"
101102
#include"pyerrors.h"
102103
#include"pythread.h"

‎Include/cpython/pytime.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// PyTime_t C API: see Doc/c-api/time.rst for the documentation.
2+
3+
#ifndefPy_LIMITED_API
4+
#ifndefPy_PYTIME_H
5+
#definePy_PYTIME_H
6+
#ifdef__cplusplus
7+
extern"C" {
8+
#endif
9+
10+
typedefint64_tPyTime_t;
11+
#definePyTime_MIN INT64_MIN
12+
#definePyTime_MAX INT64_MAX
13+
14+
PyAPI_FUNC(double)PyTime_AsSecondsDouble(PyTime_tt);
15+
PyAPI_FUNC(int)PyTime_Monotonic(PyTime_t*result);
16+
PyAPI_FUNC(int)PyTime_PerfCounter(PyTime_t*result);
17+
PyAPI_FUNC(int)PyTime_Time(PyTime_t*result);
18+
19+
#ifdef__cplusplus
20+
}
21+
#endif
22+
#endif/* Py_PYTIME_H */
23+
#endif/* Py_LIMITED_API */

‎Include/internal/pycore_time.h

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,51 @@
1-
// The _PyTime_t API is written to use timestamp and timeout values stored in
2-
// various formats and to read clocks.
1+
// Internal PyTime_t C API: see Doc/c-api/time.rst for the documentation.
32
//
4-
// The_PyTime_t type is an integer to support directly common arithmetic
5-
// operationslike t1 + t2.
3+
// ThePyTime_t type is an integer to support directly common arithmetic
4+
// operationssuch as t1 + t2.
65
//
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].
6+
// Time formats:
117
//
12-
// Formats:
8+
// * Seconds.
9+
// * Seconds as a floating point number (C double).
10+
// * Milliseconds (10^-3 seconds).
11+
// * Microseconds (10^-6 seconds).
12+
// * 100 nanoseconds (10^-7 seconds), used on Windows.
13+
// * Nanoseconds (10^-9 seconds).
14+
// * timeval structure, 1 microsecond (10^-6 seconds).
15+
// * timespec structure, 1 nanosecond (10^-9 seconds).
1316
//
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)
17+
// Note that PyTime_t is now specified as int64_t, in nanoseconds.
18+
// (If we need to change this, we'll need new public API with new names.)
19+
// Previously, PyTime_t was configurable (in theory); some comments and code
20+
// might still allude to that.
2221
//
2322
// 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).
23+
// resolution larger than 1 nanosecond is rounded correctly with the requested
24+
// rounding mode. Available rounding modes:
2725
//
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.
26+
// * Round towards minus infinity (-inf). For example, used to read a clock.
27+
// * Round towards infinity (+inf). For example, used for timeout to wait "at
28+
// least" N seconds.
29+
// * Round to nearest with ties going to nearest even integer. For example, used
30+
// to round from a Python float.
31+
// * Round away from zero. For example, used for timeout.
32+
//
33+
// Some functions clamp the result in the range [PyTime_MIN; PyTime_MAX]. The
34+
// caller doesn't have to handle errors and so doesn't need to hold the GIL to
35+
// handle exceptions. For example, _PyTime_Add(t1, t2) computes t1+t2 and
36+
// clamps the result on overflow.
3237
//
3338
// Clocks:
3439
//
3540
// * System clock
3641
// * Monotonic clock
3742
// * Performance counter
3843
//
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().
44+
// Internally, operations like (t * k / q) with integers are implemented in a
45+
// way to reduce the risk of integer overflow. Such operation is used to convert a
46+
// clock value expressed in ticks with a frequency to PyTime_t, like
47+
// QueryPerformanceCounter() with QueryPerformanceFrequency() on Windows.
48+
4349

4450
#ifndefPy_INTERNAL_TIME_H
4551
#definePy_INTERNAL_TIME_H
@@ -56,14 +62,7 @@ extern "C" {
5662
structtimeval;
5763
#endif
5864

59-
// _PyTime_t: Python timestamp with subsecond precision. It can be used to
60-
// store a duration, and so indirectly a date (related to another date, like
61-
// UNIX epoch).
62-
typedefint64_t_PyTime_t;
63-
// _PyTime_MIN nanoseconds is around -292.3 years
64-
#define_PyTime_MIN INT64_MIN
65-
// _PyTime_MAX nanoseconds is around +292.3 years
66-
#define_PyTime_MAX INT64_MAX
65+
typedefPyTime_t_PyTime_t;
6766
#define_SIZEOF_PYTIME_T 8
6867

6968
typedefenum {
@@ -147,7 +146,7 @@ PyAPI_FUNC(_PyTime_t) _PyTime_FromSecondsDouble(double seconds, _PyTime_round_t
147146
PyAPI_FUNC(_PyTime_t)_PyTime_FromNanoseconds(_PyTime_tns);
148147

149148
// Create a timestamp from a number of microseconds.
150-
// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
149+
// Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
151150
extern_PyTime_t_PyTime_FromMicrosecondsClamp(_PyTime_tus);
152151

153152
// Create a timestamp from nanoseconds (Python int).
@@ -169,10 +168,6 @@ PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
169168
PyObject*obj,
170169
_PyTime_round_tround);
171170

172-
// Convert a timestamp to a number of seconds as a C double.
173-
// Export for '_socket' shared extension.
174-
PyAPI_FUNC(double)_PyTime_AsSecondsDouble(_PyTime_tt);
175-
176171
// Convert timestamp to a number of milliseconds (10^-3 seconds).
177172
// Export for '_ssl' shared extension.
178173
PyAPI_FUNC(_PyTime_t)_PyTime_AsMilliseconds(_PyTime_tt,
@@ -183,9 +178,6 @@ PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
183178
PyAPI_FUNC(_PyTime_t)_PyTime_AsMicroseconds(_PyTime_tt,
184179
_PyTime_round_tround);
185180

186-
// Convert timestamp to a number of nanoseconds (10^-9 seconds).
187-
extern_PyTime_t_PyTime_AsNanoseconds(_PyTime_tt);
188-
189181
#ifdefMS_WINDOWS
190182
// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
191183
extern_PyTime_t_PyTime_As100Nanoseconds(_PyTime_tt,
@@ -250,7 +242,7 @@ PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts);
250242
#endif
251243

252244

253-
// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
245+
// Compute t1 + t2. Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
254246
extern_PyTime_t_PyTime_Add(_PyTime_tt1,_PyTime_tt2);
255247

256248
// Structure used by time.get_clock_info()
@@ -267,7 +259,8 @@ typedef struct {
267259
// On integer overflow, silently ignore the overflow and clamp the clock to
268260
// [_PyTime_MIN; _PyTime_MAX].
269261
//
270-
// Use _PyTime_GetSystemClockWithInfo() to check for failure.
262+
// Use _PyTime_GetSystemClockWithInfo or the public PyTime_Time() to check
263+
// for failure.
271264
// Export for '_random' shared extension.
272265
PyAPI_FUNC(_PyTime_t)_PyTime_GetSystemClock(void);
273266

@@ -287,7 +280,8 @@ extern int _PyTime_GetSystemClockWithInfo(
287280
// On integer overflow, silently ignore the overflow and clamp the clock to
288281
// [_PyTime_MIN; _PyTime_MAX].
289282
//
290-
// Use _PyTime_GetMonotonicClockWithInfo() to check for failure.
283+
// Use _PyTime_GetMonotonicClockWithInfo or the public PyTime_Monotonic()
284+
// to check for failure.
291285
// Export for '_random' shared extension.
292286
PyAPI_FUNC(_PyTime_t)_PyTime_GetMonotonicClock(void);
293287

@@ -322,10 +316,12 @@ PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
322316
// On integer overflow, silently ignore the overflow and clamp the clock to
323317
// [_PyTime_MIN; _PyTime_MAX].
324318
//
325-
// Use _PyTime_GetPerfCounterWithInfo() to check for failure.
319+
// Use _PyTime_GetPerfCounterWithInfo() or the public PyTime_PerfCounter
320+
// to check for failure.
326321
// Export for '_lsprof' shared extension.
327322
PyAPI_FUNC(_PyTime_t)_PyTime_GetPerfCounter(void);
328323

324+
329325
// Get the performance counter: clock with the highest available resolution to
330326
// measure a short duration.
331327
//
@@ -336,6 +332,13 @@ extern int _PyTime_GetPerfCounterWithInfo(
336332
_PyTime_t*t,
337333
_Py_clock_info_t*info);
338334

335+
// Alias for backward compatibility
336+
#define_PyTime_MIN PyTime_MIN
337+
#define_PyTime_MAX PyTime_MAX
338+
#define_PyTime_AsSecondsDouble PyTime_AsSecondsDouble
339+
340+
341+
// --- _PyDeadline -----------------------------------------------------------
339342

340343
// Create a deadline.
341344
// Pseudo code: _PyTime_GetMonotonicClock() + timeout.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp