summaryrefslogtreecommitdiffstats
path: root/Modules/timemodule.c
diff options
context:
space:
mode:
authorDong-hee Na <donghee.na@python.org>2021-11-16 13:41:20 (GMT)
committerGitHub <noreply@github.com>2021-11-16 13:41:20 (GMT)
commit55868f1a335cd3853938082a5b25cfba66563135 (patch)
treed20d02ea465f12080bba5c2934609eee146c9dd4 /Modules/timemodule.c
parent8b06d01507fd708468570eaa43a349828784489a (diff)
downloadcpython-55868f1a335cd3853938082a5b25cfba66563135.zip
cpython-55868f1a335cd3853938082a5b25cfba66563135.tar.gz
cpython-55868f1a335cd3853938082a5b25cfba66563135.tar.bz2
bpo-45429: Support CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if possible (GH-29203)
Diffstat (limited to 'Modules/timemodule.c')
-rw-r--r--Modules/timemodule.c40
1 files changed, 31 insertions, 9 deletions
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;