mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[NTOSKRNL]
Refactor KeUpdateSystemTime, improving readability, fixing a concurrency issue and fixing the code for 64 bit. svn path=/trunk/; revision=55174
This commit is contained in:
parent
c707066acb
commit
3468e87b38
1 changed files with 63 additions and 66 deletions
|
@ -21,71 +21,31 @@ BOOLEAN KiTimeAdjustmentEnabled = FALSE;
|
|||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||
IN ULONG Increment,
|
||||
IN KIRQL Irql)
|
||||
FORCEINLINE
|
||||
KiWriteSystemTime(volatile KSYSTEM_TIME *SystemTime, ULARGE_INTEGER NewTime)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
ULARGE_INTEGER CurrentTime, InterruptTime;
|
||||
ULONG Hand, OldTickCount;
|
||||
#ifdef _WIN64
|
||||
/* Do a single atomic write */
|
||||
*(ULONGLONG*)SystemTime = NewTime.QuadPart;
|
||||
#else
|
||||
/* Update in 3 steps, so that a reader can recognize partial updates */
|
||||
SystemTime->High1Time = NewTime.HighPart;
|
||||
SystemTime->LowPart = NewTime.LowPart;
|
||||
SystemTime->High2Time = NewTime.HighPart;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add the increment time to the shared data */
|
||||
InterruptTime.HighPart = SharedUserData->InterruptTime.High1Time;
|
||||
InterruptTime.LowPart = SharedUserData->InterruptTime.LowPart;
|
||||
InterruptTime.QuadPart += Increment;
|
||||
SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart;
|
||||
SharedUserData->InterruptTime.LowPart = InterruptTime.LowPart;
|
||||
SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart;
|
||||
|
||||
/* Update tick count */
|
||||
InterlockedExchangeAdd(&KiTickOffset, -(LONG)Increment);
|
||||
|
||||
/* Check for incomplete tick */
|
||||
OldTickCount = KeTickCount.LowPart;
|
||||
if (KiTickOffset <= 0)
|
||||
{
|
||||
/* Update the system time */
|
||||
CurrentTime.HighPart = SharedUserData->SystemTime.High1Time;
|
||||
CurrentTime.LowPart = SharedUserData->SystemTime.LowPart;
|
||||
CurrentTime.QuadPart += KeTimeAdjustment;
|
||||
SharedUserData->SystemTime.High2Time = CurrentTime.HighPart;
|
||||
SharedUserData->SystemTime.LowPart = CurrentTime.LowPart;
|
||||
SharedUserData->SystemTime.High1Time = CurrentTime.HighPart;
|
||||
|
||||
/* Update the tick count */
|
||||
CurrentTime.HighPart = KeTickCount.High1Time;
|
||||
CurrentTime.LowPart = OldTickCount;
|
||||
CurrentTime.QuadPart += 1;
|
||||
KeTickCount.High2Time = CurrentTime.HighPart;
|
||||
KeTickCount.LowPart = CurrentTime.LowPart;
|
||||
KeTickCount.High1Time = CurrentTime.HighPart;
|
||||
|
||||
/* Update it in the shared user data */
|
||||
SharedUserData->TickCount.High2Time = CurrentTime.HighPart;
|
||||
SharedUserData->TickCount.LowPart = CurrentTime.LowPart;
|
||||
SharedUserData->TickCount.High1Time = CurrentTime.HighPart;
|
||||
|
||||
/* Check for timer expiration */
|
||||
Hand = OldTickCount & (TIMER_TABLE_SIZE - 1);
|
||||
if (KiTimerTableListHead[Hand].Time.QuadPart <= InterruptTime.QuadPart)
|
||||
{
|
||||
/* Check if we are already doing expiration */
|
||||
if (!Prcb->TimerRequest)
|
||||
{
|
||||
/* Request a DPC to handle this */
|
||||
Prcb->TimerRequest = (ULONG_PTR)TrapFrame;
|
||||
Prcb->TimerHand = Hand;
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for expiration with the new tick count as well */
|
||||
OldTickCount++;
|
||||
}
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiCheckForTimerExpiration(
|
||||
PKPRCB Prcb,
|
||||
PKTRAP_FRAME TrapFrame,
|
||||
ULARGE_INTEGER InterruptTime)
|
||||
{
|
||||
ULONG Hand;
|
||||
|
||||
/* Check for timer expiration */
|
||||
Hand = OldTickCount & (TIMER_TABLE_SIZE - 1);
|
||||
Hand = KeTickCount.LowPart & (TIMER_TABLE_SIZE - 1);
|
||||
if (KiTimerTableListHead[Hand].Time.QuadPart <= InterruptTime.QuadPart)
|
||||
{
|
||||
/* Check if we are already doing expiration */
|
||||
|
@ -97,19 +57,56 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
|||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if this was a full tick */
|
||||
if (KiTickOffset <= 0)
|
||||
VOID
|
||||
FASTCALL
|
||||
KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||
IN ULONG Increment,
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
ULARGE_INTEGER CurrentTime, InterruptTime;
|
||||
LONG OldTickOffset;
|
||||
|
||||
/* Add the increment time to the shared data */
|
||||
InterruptTime.QuadPart = *(ULONGLONG*)&SharedUserData->InterruptTime;
|
||||
InterruptTime.QuadPart += Increment;
|
||||
KiWriteSystemTime(&SharedUserData->InterruptTime, InterruptTime);
|
||||
|
||||
/* Check for timer expiration */
|
||||
KiCheckForTimerExpiration(Prcb, TrapFrame, InterruptTime);
|
||||
|
||||
/* Update the tick offset */
|
||||
OldTickOffset = InterlockedExchangeAdd(&KiTickOffset, -(LONG)Increment);
|
||||
|
||||
/* Check for full tick */
|
||||
if (OldTickOffset <= (LONG)Increment)
|
||||
{
|
||||
/* Update the tick offset */
|
||||
/* Update the system time */
|
||||
CurrentTime.QuadPart = *(ULONGLONG*)&SharedUserData->SystemTime;
|
||||
CurrentTime.QuadPart += KeTimeAdjustment;
|
||||
KiWriteSystemTime(&SharedUserData->SystemTime, CurrentTime);
|
||||
|
||||
/* Update the tick count */
|
||||
CurrentTime.QuadPart = (*(ULONGLONG*)&KeTickCount) + 1;
|
||||
KiWriteSystemTime(&KeTickCount, CurrentTime);
|
||||
|
||||
/* Update it in the shared user data */
|
||||
KiWriteSystemTime(&SharedUserData->TickCount, CurrentTime);
|
||||
|
||||
/* Check for expiration with the new tick count as well */
|
||||
KiCheckForTimerExpiration(Prcb, TrapFrame, InterruptTime);
|
||||
|
||||
/* Reset the tick offset */
|
||||
KiTickOffset += KeMaximumIncrement;
|
||||
|
||||
/* Update system runtime */
|
||||
/* Update processor/thread runtime */
|
||||
KeUpdateRunTime(TrapFrame, Irql);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase interrupt count and exit */
|
||||
/* Increase interrupt count only */
|
||||
Prcb->InterruptCount++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue