summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2024-03-18 16:13:01 (GMT)
committerGitHub <noreply@github.com>2024-03-18 16:13:01 (GMT)
commit1d95451be1f3080904c00cc4c4a6cc519efdf321 (patch)
treec76d159aac129fd799bee2ac5dce507e6d803097
parentc80d2d3263b3caf579777fd2a98399aeb3497f23 (diff)
downloadcpython-1d95451be1f3080904c00cc4c4a6cc519efdf321.zip
cpython-1d95451be1f3080904c00cc4c4a6cc519efdf321.tar.gz
cpython-1d95451be1f3080904c00cc4c4a6cc519efdf321.tar.bz2
gh-63207: Use GetSystemTimePreciseAsFileTime() in time.time() (#116822)
-rw-r--r--Doc/whatsnew/3.13.rst6
-rw-r--r--Misc/NEWS.d/next/Library/2024-03-14-17-21-25.gh-issue-63207.LV16SL.rst4
-rw-r--r--Python/pytime.c38
3 files changed, 32 insertions, 16 deletions
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index a48db94..b665e6f 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -570,6 +570,12 @@ time
instead of the ``GetTickCount64()`` clock which has a resolution of 15.6 ms.
(Contributed by Victor Stinner in :gh:`88494`.)
+* On Windows, :func:`time.time()` now uses the
+ ``GetSystemTimePreciseAsFileTime()`` clock to have a resolution better
+ than 1 us, instead of the ``GetSystemTimeAsFileTime()`` clock which has a
+ resolution of 15.6 ms.
+ (Contributed by Victor Stinner in :gh:`63207`.)
+
tkinter
-------
diff --git a/Misc/NEWS.d/next/Library/2024-03-14-17-21-25.gh-issue-63207.LV16SL.rst b/Misc/NEWS.d/next/Library/2024-03-14-17-21-25.gh-issue-63207.LV16SL.rst
new file mode 100644
index 0000000..1f77555
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-03-14-17-21-25.gh-issue-63207.LV16SL.rst
@@ -0,0 +1,4 @@
+On Windows, :func:`time.time()` now uses the
+``GetSystemTimePreciseAsFileTime()`` clock to have a resolution better than 1
+us, instead of the ``GetSystemTimeAsFileTime()`` clock which has a resolution
+of 15.6 ms. Patch by Victor Stinner.
diff --git a/Python/pytime.c b/Python/pytime.c
index 45be6a3..d5b3804 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -55,6 +55,14 @@
#endif
+#ifdef MS_WINDOWS
+static _PyTimeFraction py_qpc_base = {0, 0};
+
+// Forward declaration
+static int py_win_perf_counter_frequency(_PyTimeFraction *base, int raise_exc);
+#endif
+
+
static PyTime_t
_PyTime_GCD(PyTime_t x, PyTime_t y)
{
@@ -895,7 +903,7 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
FILETIME system_time;
ULARGE_INTEGER large;
- GetSystemTimeAsFileTime(&system_time);
+ GetSystemTimePreciseAsFileTime(&system_time);
large.u.LowPart = system_time.dwLowDateTime;
large.u.HighPart = system_time.dwHighDateTime;
/* 11,644,473,600,000,000,000: number of nanoseconds between
@@ -904,18 +912,17 @@ py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
PyTime_t ns = large.QuadPart * 100 - 11644473600000000000;
*tp = ns;
if (info) {
- DWORD timeAdjustment, timeIncrement;
- BOOL isTimeAdjustmentDisabled, ok;
+ // GetSystemTimePreciseAsFileTime() is implemented using
+ // QueryPerformanceCounter() internally.
+ if (py_qpc_base.denom == 0) {
+ if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
+ return -1;
+ }
+ }
- info->implementation = "GetSystemTimeAsFileTime()";
+ info->implementation = "GetSystemTimePreciseAsFileTime()";
info->monotonic = 0;
- ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
- &isTimeAdjustmentDisabled);
- if (!ok) {
- PyErr_SetFromWindowsErr(0);
- return -1;
- }
- info->resolution = timeIncrement * 1e-7;
+ info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
info->adjustable = 1;
}
@@ -1063,16 +1070,15 @@ py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{
assert(info == NULL || raise_exc);
- static _PyTimeFraction base = {0, 0};
- if (base.denom == 0) {
- if (py_win_perf_counter_frequency(&base, raise_exc) < 0) {
+ if (py_qpc_base.denom == 0) {
+ if (py_win_perf_counter_frequency(&py_qpc_base, raise_exc) < 0) {
return -1;
}
}
if (info) {
info->implementation = "QueryPerformanceCounter()";
- info->resolution = _PyTimeFraction_Resolution(&base);
+ info->resolution = _PyTimeFraction_Resolution(&py_qpc_base);
info->monotonic = 1;
info->adjustable = 0;
}
@@ -1088,7 +1094,7 @@ py_get_win_perf_counter(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
"LONGLONG is larger than PyTime_t");
ticks = (PyTime_t)ticksll;
- *tp = _PyTimeFraction_Mul(ticks, &base);
+ *tp = _PyTimeFraction_Mul(ticks, &py_qpc_base);
return 0;
}
#endif // MS_WINDOWS