Skip to content

Commit 449e6f0

Browse files
authored
bpo-41299: Reduce lag in Windows threading timeouts by using a higher precision time source (GH-26568)
1 parent 2ab27c4 commit 449e6f0

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix 16ms jitter when using timeouts in :mod:`threading`, such as with :meth:`threading.Lock.acquire` or :meth:`threading.Condition.wait`.

Python/thread_nt.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,22 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
7676
}
7777
} else if (milliseconds != 0) {
7878
/* wait at least until the target */
79-
ULONGLONG now, target = GetTickCount64() + milliseconds;
79+
_PyTime_t now = _PyTime_GetPerfCounter();
80+
if (now <= 0) {
81+
Py_FatalError("_PyTime_GetPerfCounter() == 0");
82+
}
83+
_PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000);
84+
_PyTime_t target = now + nanoseconds;
8085
while (mutex->locked) {
81-
if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (long long)milliseconds*1000) < 0) {
86+
_PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, _PyTime_ROUND_TIMEOUT);
87+
if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) {
8288
result = WAIT_FAILED;
8389
break;
8490
}
85-
now = GetTickCount64();
91+
now = _PyTime_GetPerfCounter();
8692
if (target <= now)
8793
break;
88-
milliseconds = (DWORD)(target-now);
94+
nanoseconds = target - now;
8995
}
9096
}
9197
if (!mutex->locked) {

0 commit comments

Comments
 (0)