bpo-41299: Reduce lag in Windows threading timeouts by using a higher precision time source (GH-26568)

This commit is contained in:
Ryan Hileman 2021-06-07 13:26:02 -07:00 committed by GitHub
parent 2ab27c4af4
commit 449e6f0ef3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 4 deletions

View file

@ -0,0 +1 @@
Fix 16ms jitter when using timeouts in :mod:`threading`, such as with :meth:`threading.Lock.acquire` or :meth:`threading.Condition.wait`.

View file

@ -76,16 +76,22 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
} }
} else if (milliseconds != 0) { } else if (milliseconds != 0) {
/* wait at least until the target */ /* 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) { 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; result = WAIT_FAILED;
break; break;
} }
now = GetTickCount64(); now = _PyTime_GetPerfCounter();
if (target <= now) if (target <= now)
break; break;
milliseconds = (DWORD)(target-now); nanoseconds = target - now;
} }
} }
if (!mutex->locked) { if (!mutex->locked) {