[Python-checkins] bpo-45429: Support CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if possible (GH-29203)

corona10 webhook-mailer at python.org
Tue Nov 16 08:41:29 EST 2021


https://github.com/python/cpython/commit/55868f1a335cd3853938082a5b25cfba66563135
commit: 55868f1a335cd3853938082a5b25cfba66563135
branch: main
author: Dong-hee Na <donghee.na at python.org>
committer: corona10 <donghee.na92 at gmail.com>
date: 2021-11-16T22:41:20+09:00
summary:

bpo-45429: Support CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if possible (GH-29203)

files:
A Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst
M Doc/whatsnew/3.11.rst
M Modules/timemodule.c

diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 62516d207d0b1..0c7c74e7c3242 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -283,6 +283,10 @@ time
   a resolution of 1 millisecond (10\ :sup:`-3` seconds).
   (Contributed by Benjamin Szőke and Victor Stinner in :issue:`21302`.)
 
+* On Windows, :func:`time.sleep` now uses a waitable timer which supports high-resolution timers.
+  In Python 3.10, the best resolution was 1 ms, from Python 3.11 it's now smaller than 1 ms.
+  (Contributed by Dong-hee Na and Eryk Sun in :issue:`45429`.)
+
 unicodedata
 -----------
 
diff --git a/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst b/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst
new file mode 100644
index 0000000000000..0a274f1ef8ab7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst
@@ -0,0 +1,2 @@
+On Windows, :func:`time.sleep` now uses a waitable timer which supports
+high-resolution timers. Patch by Dong-hee Na and Eryk Sun.
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 0ef3b2ffaa898..bb713908eb1e4 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -408,6 +408,13 @@ static PyStructSequence_Desc struct_time_type_desc = {
 static int initialized;
 static PyTypeObject StructTimeType;
 
+#if defined(MS_WINDOWS)
+#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
+  #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
+#endif
+
+static DWORD timer_flags = (DWORD)-1;
+#endif
 
 static PyObject *
 tmtotuple(struct tm *p
@@ -2017,6 +2024,23 @@ time_exec(PyObject *module)
         utc_string = tm.tm_zone;
 #endif
 
+#if defined(MS_WINDOWS)
+    if (timer_flags == (DWORD)-1) {
+        DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
+        HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags,
+                                              TIMER_ALL_ACCESS);
+        if (timer == NULL) {
+            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported.
+            timer_flags = 0;
+        }
+        else {
+            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported.
+            timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
+            CloseHandle(timer);
+        }
+    }
+#endif
+
     return 0;
 }
 
@@ -2150,20 +2174,18 @@ pysleep(_PyTime_t timeout)
     // SetWaitableTimer(): a negative due time indicates relative time
     relative_timeout.QuadPart = -timeout_100ns;
 
-    HANDLE timer = CreateWaitableTimerW(NULL, FALSE, NULL);
+    HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags,
+                                          TIMER_ALL_ACCESS);
     if (timer == NULL) {
         PyErr_SetFromWindowsErr(0);
         return -1;
     }
 
-    if (!SetWaitableTimer(timer, &relative_timeout,
-                          // period: the timer is signaled once
-                          0,
-                          // no completion routine
-                          NULL, NULL,
-                          // Don't restore a system in suspended power
-                          // conservation mode when the timer is signaled.
-                          FALSE))
+    if (!SetWaitableTimerEx(timer, &relative_timeout,
+                            0, // no period; the timer is signaled once
+                            NULL, NULL, // no completion routine
+                            NULL,  // no wake context; do not resume from suspend
+                            0)) // no tolerable delay for timer coalescing
     {
         PyErr_SetFromWindowsErr(0);
         goto error;



More information about the Python-checkins mailing list