From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 11 Jun 2021 22:03:10 +0000 (-0700) Subject: bpo-41299: Reduce lag in Windows threading timeouts by using a higher precision time... X-Git-Tag: v3.9.6~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57b3ca7f0aef4d180038d475398f809d3fcdd8be;p=thirdparty%2FPython%2Fcpython.git bpo-41299: Reduce lag in Windows threading timeouts by using a higher precision time source (GH-26568) (cherry picked from commit 449e6f0ef395231e3abe467f910b02d7f075c27f) Co-authored-by: Ryan Hileman --- diff --git a/Misc/NEWS.d/next/Windows/2021-06-06-16-36-13.bpo-41299.Rg-vb_.rst b/Misc/NEWS.d/next/Windows/2021-06-06-16-36-13.bpo-41299.Rg-vb_.rst new file mode 100644 index 000000000000..71f700ffa155 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2021-06-06-16-36-13.bpo-41299.Rg-vb_.rst @@ -0,0 +1 @@ +Fix 16ms jitter when using timeouts in :mod:`threading`, such as with :meth:`threading.Lock.acquire` or :meth:`threading.Condition.wait`. diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 05b982d32dc5..0ce5e94f89bf 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -76,16 +76,22 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) } } else if (milliseconds != 0) { /* wait at least until the target */ - ULONGLONG now, target = GetTickCount64() + milliseconds; + _PyTime_t now = _PyTime_GetPerfCounter(); + if (now <= 0) { + Py_FatalError("_PyTime_GetPerfCounter() == 0"); + } + _PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000); + _PyTime_t target = now + nanoseconds; while (mutex->locked) { - if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (long long)milliseconds*1000) < 0) { + _PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, _PyTime_ROUND_TIMEOUT); + if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) { result = WAIT_FAILED; break; } - now = GetTickCount64(); + now = _PyTime_GetPerfCounter(); if (target <= now) break; - milliseconds = (DWORD)(target-now); + nanoseconds = target - now; } } if (!mutex->locked) {