https://github.com/python/cpython/commit/1d95451be1f3080904c00cc4c4a6cc519efdf321
commit: 1d95451be1f3080904c00cc4c4a6cc519efdf321
branch: main
author: Victor Stinner <vstin...@python.org>
committer: vstinner <vstin...@python.org>
date: 2024-03-18T17:13:01+01:00
summary:

gh-63207: Use GetSystemTimePreciseAsFileTime() in time.time() (#116822)

files:
A Misc/NEWS.d/next/Library/2024-03-14-17-21-25.gh-issue-63207.LV16SL.rst
M Doc/whatsnew/3.13.rst
M Python/pytime.c

diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index a48db949d8f401..b665e6f1c85915 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 00000000000000..1f77555d5e7d31
--- /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 45be6a3dbd3341..d5b38047b6db31 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

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to