]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41299: Reduce lag in Windows threading timeouts by using a higher precision time...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 11 Jun 2021 22:03:10 +0000 (15:03 -0700)
committerGitHub <noreply@github.com>
Fri, 11 Jun 2021 22:03:10 +0000 (15:03 -0700)
(cherry picked from commit 449e6f0ef395231e3abe467f910b02d7f075c27f)

Co-authored-by: Ryan Hileman <lunixbochs@gmail.com>
Misc/NEWS.d/next/Windows/2021-06-06-16-36-13.bpo-41299.Rg-vb_.rst [new file with mode: 0644]
Python/thread_nt.h

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 (file)
index 0000000..71f700f
--- /dev/null
@@ -0,0 +1 @@
+Fix 16ms jitter when using timeouts in :mod:`threading`, such as with :meth:`threading.Lock.acquire` or :meth:`threading.Condition.wait`.
index 05b982d32dc52602ffc9616b78018e1850d438ba..0ce5e94f89bf72dfde09916088e6682ed9ad1e83 100644 (file)
@@ -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) {