Implement clock interrupt handling and time increment configuration
All checks were successful
All checks were successful
This commit is contained in:
@@ -19,6 +19,10 @@ namespace KE
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
STATIC LARGE_INTEGER BootTime;
|
STATIC LARGE_INTEGER BootTime;
|
||||||
|
STATIC ULONG MaximumIncrement;
|
||||||
|
STATIC ULONG MinimumIncrement;
|
||||||
|
STATIC LONG TickOffset;
|
||||||
|
STATIC ULONG TimeAdjustment;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI VOID GetSystemTime(OUT PLARGE_INTEGER SystemTime);
|
STATIC XTAPI VOID GetSystemTime(OUT PLARGE_INTEGER SystemTime);
|
||||||
@@ -26,6 +30,11 @@ namespace KE
|
|||||||
OUT PLARGE_INTEGER OldTime,
|
OUT PLARGE_INTEGER OldTime,
|
||||||
IN BOOLEAN AdjustInterruptTime,
|
IN BOOLEAN AdjustInterruptTime,
|
||||||
IN BOOLEAN WriteToRtc);
|
IN BOOLEAN WriteToRtc);
|
||||||
|
STATIC XTAPI VOID SetTimeIncrement(IN ULONG MinIncrement,
|
||||||
|
IN ULONG MaxIncrement);
|
||||||
|
STATIC XTFASTCALL VOID UpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Increment,
|
||||||
|
IN KRUNLEVEL RunLevel);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,3 +77,15 @@ KSPIN_LOCK KE::SystemResources::ResourcesLock;
|
|||||||
|
|
||||||
/* Kernel boot time */
|
/* Kernel boot time */
|
||||||
LARGE_INTEGER KE::SystemTime::BootTime;
|
LARGE_INTEGER KE::SystemTime::BootTime;
|
||||||
|
|
||||||
|
/* The maximum interval between system clock interrupts */
|
||||||
|
ULONG KE::SystemTime::MaximumIncrement;
|
||||||
|
|
||||||
|
/* The minimum interval between system clock interrupts */
|
||||||
|
ULONG KE::SystemTime::MinimumIncrement;
|
||||||
|
|
||||||
|
/* Accumulator tracking fractional ticks, decremented until a full tick elapses */
|
||||||
|
LONG KE::SystemTime::TickOffset;
|
||||||
|
|
||||||
|
/* The runtime adjustment value applied to the system clock at each interrupt */
|
||||||
|
ULONG KE::SystemTime::TimeAdjustment;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current system time.
|
* Returns the current system time.
|
||||||
*
|
*
|
||||||
@@ -97,3 +98,85 @@ KE::SystemTime::SetSystemTime(IN PLARGE_INTEGER NewTime,
|
|||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum and minimum time increment values in 100ns units.
|
||||||
|
*
|
||||||
|
* @param MinIncrement
|
||||||
|
* Supplies the minimum time increment.
|
||||||
|
*
|
||||||
|
* @param MaxIncrement
|
||||||
|
* Supplies the maximum time increment.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
KE::SystemTime::SetTimeIncrement(IN ULONG MinIncrement,
|
||||||
|
IN ULONG MaxIncrement)
|
||||||
|
{
|
||||||
|
/* Store resolution boundaries while enforcing a 1ms architectural floor */
|
||||||
|
MaximumIncrement = MaxIncrement;
|
||||||
|
MinimumIncrement = MAX(MinIncrement, 10000);
|
||||||
|
|
||||||
|
/* Set the tick offset to the maximum increment */
|
||||||
|
TickOffset = (LONG)MaxIncrement;
|
||||||
|
|
||||||
|
/* Set the default time adjustment to the full tick period */
|
||||||
|
TimeAdjustment = MaxIncrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Services the periodic clock interrupt by advancing the global interrupt time, detecting full
|
||||||
|
* system tick boundaries via the tick offset accumulator, and advancing the wall-clock system time.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a pointer to the hardware trap frame representing the interrupted execution context.
|
||||||
|
*
|
||||||
|
* @param Increment
|
||||||
|
* Supplies the calibrated time delta for this hardware interrupt in 100-nanosecond units.
|
||||||
|
*
|
||||||
|
* @param RunLevel
|
||||||
|
* Supplies the system run level at which the interrupt was taken.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
KE::SystemTime::UpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Increment,
|
||||||
|
IN KRUNLEVEL RunLevel)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER InterruptTime, SystemTime;
|
||||||
|
LONG CurrentTickOffset;
|
||||||
|
|
||||||
|
/* Advance the global interrupt time on every hardware tick */
|
||||||
|
InterruptTime = KE::SharedData::GetInterruptTime();
|
||||||
|
InterruptTime.QuadPart += Increment;
|
||||||
|
KE::SharedData::SetInterruptTime(InterruptTime);
|
||||||
|
|
||||||
|
/* Atomically consume the current tick budget and retrieve the pre-decrement value */
|
||||||
|
CurrentTickOffset = RTL::Atomic::ExchangeAdd32((PLONG)&TickOffset, -(LONG)Increment);
|
||||||
|
|
||||||
|
/* Determine whether the accumulated increments have crossed the full tick boundary */
|
||||||
|
if(CurrentTickOffset <= (LONG)Increment)
|
||||||
|
{
|
||||||
|
/* A full system tick has elapsed, advance the wall-clock time by the configured adjustment */
|
||||||
|
SystemTime = KE::SharedData::GetSystemTime();
|
||||||
|
SystemTime.QuadPart += TimeAdjustment;
|
||||||
|
KE::SharedData::SetSystemTime(SystemTime);
|
||||||
|
|
||||||
|
/* Update the tick count */
|
||||||
|
KE::SharedData::IncrementTickCount();
|
||||||
|
|
||||||
|
/* Reload the tick offset accumulator for the next full tick period */
|
||||||
|
TickOffset += MaximumIncrement;
|
||||||
|
|
||||||
|
/* Update processor and thread runtime accounting */
|
||||||
|
KE::Dispatcher::UpdateRunTime(TrapFrame, RunLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user