diff options
author | Dong-hee Na <donghee.na@python.org> | 2021-11-16 13:41:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-16 13:41:20 (GMT) |
commit | 55868f1a335cd3853938082a5b25cfba66563135 (patch) | |
tree | d20d02ea465f12080bba5c2934609eee146c9dd4 | |
parent | 8b06d01507fd708468570eaa43a349828784489a (diff) | |
download | cpython-55868f1a335cd3853938082a5b25cfba66563135.zip cpython-55868f1a335cd3853938082a5b25cfba66563135.tar.gz cpython-55868f1a335cd3853938082a5b25cfba66563135.tar.bz2 |
bpo-45429: Support CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if possible (GH-29203)
-rw-r--r-- | Doc/whatsnew/3.11.rst | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst | 2 | ||||
-rw-r--r-- | Modules/timemodule.c | 40 |
3 files changed, 37 insertions, 9 deletions
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 62516d2..0c7c74e 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 0000000..0a274f1 --- /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 0ef3b2f..bb71390 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; |