Account for partial milliseconds in KiClockIsr
This fixes the slowness in The lord of the rings: the third era
This commit is contained in:
parent
c7b028b3e7
commit
46d0173673
|
@ -102,7 +102,7 @@ static uint64_t pit_next(uint64_t now)
|
|||
uint64_t next = pit_last + pit_period;
|
||||
|
||||
if (now >= next) {
|
||||
xbox::KiClockIsr((now - pit_last - pit_period) / 1000);
|
||||
xbox::KiClockIsr(now - pit_last);
|
||||
pit_last = get_now();
|
||||
return pit_period;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ static uint64_t get_next(uint64_t now)
|
|||
xbox::void_xt NTAPI system_events(xbox::PVOID arg)
|
||||
{
|
||||
// Testing shows that, if this thread has the same priority of the other xbox threads, it can take tens, even hundreds of ms to complete a single loop.
|
||||
// So we increase its priority to above normal, so that it completes a loop roughly every 3.1ms
|
||||
// So we increase its priority to above normal, so that it scheduled more often
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
while (true) {
|
||||
|
|
|
@ -146,19 +146,25 @@ xbox::void_xt xbox::KiWaitListUnlock()
|
|||
KiWaitListMtx.Mtx.unlock();
|
||||
}
|
||||
|
||||
xbox::void_xt xbox::KiClockIsr(ulonglong_xt ExtraMs)
|
||||
xbox::void_xt xbox::KiClockIsr(ulonglong_xt TotalUs)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LARGE_INTEGER InterruptTime, SystemTime;
|
||||
ULONG Hand;
|
||||
DWORD OldKeTickCount;
|
||||
static uint64_t LostUs;
|
||||
uint64_t TotalMs = TotalUs / 1000;
|
||||
LostUs += (TotalUs - TotalMs * 1000);
|
||||
uint64_t RecoveredMs = LostUs / 1000;
|
||||
TotalMs += RecoveredMs;
|
||||
LostUs -= (RecoveredMs * 1000);
|
||||
|
||||
OldIrql = KfRaiseIrql(CLOCK_LEVEL);
|
||||
|
||||
// Update the interrupt time
|
||||
InterruptTime.u.LowPart = KeInterruptTime.LowPart;
|
||||
InterruptTime.u.HighPart = KeInterruptTime.High1Time;
|
||||
InterruptTime.QuadPart += (CLOCK_TIME_INCREMENT * (1 + ExtraMs));
|
||||
InterruptTime.QuadPart += (CLOCK_TIME_INCREMENT * TotalMs);
|
||||
KeInterruptTime.High2Time = InterruptTime.u.HighPart;
|
||||
KeInterruptTime.LowPart = InterruptTime.u.LowPart;
|
||||
KeInterruptTime.High1Time = InterruptTime.u.HighPart;
|
||||
|
@ -178,7 +184,7 @@ xbox::void_xt xbox::KiClockIsr(ulonglong_xt ExtraMs)
|
|||
else {
|
||||
SystemTime.u.LowPart = KeSystemTime.LowPart;
|
||||
SystemTime.u.HighPart = KeSystemTime.High1Time;
|
||||
SystemTime.QuadPart += (CLOCK_TIME_INCREMENT * (1 + ExtraMs));
|
||||
SystemTime.QuadPart += (CLOCK_TIME_INCREMENT * TotalMs);
|
||||
KeSystemTime.High2Time = SystemTime.u.HighPart;
|
||||
KeSystemTime.LowPart = SystemTime.u.LowPart;
|
||||
KeSystemTime.High1Time = SystemTime.u.HighPart;
|
||||
|
@ -186,7 +192,7 @@ xbox::void_xt xbox::KiClockIsr(ulonglong_xt ExtraMs)
|
|||
|
||||
// Update the tick counter
|
||||
OldKeTickCount = KeTickCount;
|
||||
KeTickCount += (1 + static_cast<dword_xt>(ExtraMs));
|
||||
KeTickCount += (1 + static_cast<dword_xt>(TotalMs));
|
||||
|
||||
// Because this function must be fast to continuously update the kernel clocks, if somebody else is currently
|
||||
// holding the lock, we won't wait and instead skip the check of the timers for this cycle
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace xbox
|
|||
|
||||
void_xt KiWaitListUnlock();
|
||||
|
||||
void_xt KiClockIsr(ulonglong_xt ExtraMs);
|
||||
void_xt KiClockIsr(ulonglong_xt TotalUs);
|
||||
|
||||
xbox::void_xt NTAPI KiCheckTimerTable
|
||||
(
|
||||
|
|
Loading…
Reference in New Issue