Implement timer table list and check for expired timers
This commit is contained in:
@@ -565,6 +565,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
KDPC_DATA DpcData[2];
|
KDPC_DATA DpcData[2];
|
||||||
PVOID DpcStack;
|
PVOID DpcStack;
|
||||||
VOLATILE BOOLEAN DpcRoutineActive;
|
VOLATILE BOOLEAN DpcRoutineActive;
|
||||||
|
VOLATILE ULONG_PTR TimerHand;
|
||||||
VOLATILE ULONG_PTR TimerRequest;
|
VOLATILE ULONG_PTR TimerRequest;
|
||||||
ULONG_PTR MultiThreadProcessorSet;
|
ULONG_PTR MultiThreadProcessorSet;
|
||||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||||
|
|||||||
@@ -525,6 +525,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
KDPC_DATA DpcData[2];
|
KDPC_DATA DpcData[2];
|
||||||
PVOID DpcStack;
|
PVOID DpcStack;
|
||||||
VOLATILE BOOLEAN DpcRoutineActive;
|
VOLATILE BOOLEAN DpcRoutineActive;
|
||||||
|
VOLATILE ULONG_PTR TimerHand;
|
||||||
VOLATILE ULONG_PTR TimerRequest;
|
VOLATILE ULONG_PTR TimerRequest;
|
||||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||||
ULONG InterruptCount;
|
ULONG InterruptCount;
|
||||||
|
|||||||
@@ -30,8 +30,9 @@
|
|||||||
/* Kernel service descriptor tables count */
|
/* Kernel service descriptor tables count */
|
||||||
#define KSERVICE_TABLES_COUNT 4
|
#define KSERVICE_TABLES_COUNT 4
|
||||||
|
|
||||||
/* Timer length */
|
/* Timer related definitions */
|
||||||
#define KTIMER_LENGTH (FIELD_OFFSET(KTIMER, Period) + sizeof(LONG))
|
#define KTIMER_LENGTH (FIELD_OFFSET(KTIMER, Period) + sizeof(LONG))
|
||||||
|
#define KTIMER_TABLE_SIZE 512
|
||||||
|
|
||||||
/* Kernel builtin wait blocks */
|
/* Kernel builtin wait blocks */
|
||||||
#define EVENT_WAIT_BLOCK 2
|
#define EVENT_WAIT_BLOCK 2
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ namespace KE
|
|||||||
{
|
{
|
||||||
class Timer
|
class Timer
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
STATIC LIST_ENTRY TimerTableListHead[KTIMER_TABLE_SIZE];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer);
|
STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer);
|
||||||
STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer);
|
STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer);
|
||||||
@@ -28,6 +31,9 @@ namespace KE
|
|||||||
IN LARGE_INTEGER DueTime,
|
IN LARGE_INTEGER DueTime,
|
||||||
IN LONG Period,
|
IN LONG Period,
|
||||||
IN PKDPC Dpc);
|
IN PKDPC Dpc);
|
||||||
|
STATIC XTAPI VOID VerifySystemTimerExpiration(IN PKPROCESSOR_CONTROL_BLOCK Prcb,
|
||||||
|
IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN LARGE_INTEGER Time);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer);
|
STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer);
|
||||||
|
|||||||
@@ -95,3 +95,6 @@ LONG KE::SystemTime::TickOffset;
|
|||||||
|
|
||||||
/* The runtime adjustment value applied to the system clock at each interrupt */
|
/* The runtime adjustment value applied to the system clock at each interrupt */
|
||||||
ULONG KE::SystemTime::TimeAdjustment;
|
ULONG KE::SystemTime::TimeAdjustment;
|
||||||
|
|
||||||
|
/* Kernel timer table containing a list of active timers */
|
||||||
|
LIST_ENTRY KE::Timer::TimerTableListHead[KTIMER_TABLE_SIZE];
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* FILE: xtoskrnl/ke/timer.cc
|
* FILE: xtoskrnl/ke/timer.cc
|
||||||
* DESCRIPTION: Kernel timer object support
|
* DESCRIPTION: Kernel timer object support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -156,6 +157,25 @@ KE::Timer::QueryTimer(IN PKTIMER Timer)
|
|||||||
return DueTime;
|
return DueTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a specified timer from the timer list.
|
||||||
|
*
|
||||||
|
* @param Timer
|
||||||
|
* Supplies a pointer to a timer object.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
KE::Timer::RemoveTimer(IN OUT PKTIMER Timer)
|
||||||
|
{
|
||||||
|
/* Remove the timer from the list */
|
||||||
|
Timer->Header.Inserted = FALSE;
|
||||||
|
RTL::LinkedList::RemoveEntryList(&Timer->TimerListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the supplied timer to expire at the specified time.
|
* Sets the supplied timer to expire at the specified time.
|
||||||
*
|
*
|
||||||
@@ -186,10 +206,17 @@ KE::Timer::SetTimer(IN PKTIMER Timer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a specified timer from the timer list.
|
* Verifies if any system timers have expired for the current tick and requests a software
|
||||||
|
* DISPATCH interrupt to process them if necessary.
|
||||||
*
|
*
|
||||||
* @param Timer
|
* @param Prcb
|
||||||
* Supplies a pointer to a timer object.
|
* Supplies a pointer to the current Processor Control Block.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a pointer to the trap frame representing the interrupted context.
|
||||||
|
*
|
||||||
|
* @param Time
|
||||||
|
* Supplies the current absolute interrupt time.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -197,9 +224,37 @@ KE::Timer::SetTimer(IN PKTIMER Timer,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
KE::Timer::RemoveTimer(IN OUT PKTIMER Timer)
|
KE::Timer::VerifySystemTimerExpiration(IN PKPROCESSOR_CONTROL_BLOCK Prcb,
|
||||||
|
IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN LARGE_INTEGER Time)
|
||||||
{
|
{
|
||||||
/* Remove the timer from the list */
|
LARGE_INTEGER TickCount;
|
||||||
Timer->Header.Inserted = FALSE;
|
ULONG TimerHand;
|
||||||
RTL::LinkedList::RemoveEntryList(&Timer->TimerListEntry);
|
PKTIMER Timer;
|
||||||
|
|
||||||
|
/* Retrieve the current system tick count and calculate the index into the timer table */
|
||||||
|
TickCount = KE::SharedData::GetTickCount();
|
||||||
|
TimerHand = TickCount.LowPart & (KTIMER_TABLE_SIZE - 1);
|
||||||
|
|
||||||
|
/* Check if there are any active timers scheduled */
|
||||||
|
if(!RTL::LinkedList::ListEmpty(&TimerTableListHead[TimerHand]))
|
||||||
|
{
|
||||||
|
/* Retrieve the first timer object from the list */
|
||||||
|
Timer = CONTAIN_RECORD((&TimerTableListHead[TimerHand])->Flink, KTIMER, TimerListEntry);
|
||||||
|
|
||||||
|
/* Check if the timer due time has been reached */
|
||||||
|
if(Timer->DueTime.QuadPart <= Time.QuadPart)
|
||||||
|
{
|
||||||
|
/* Ensure there is no pending timer expiration request */
|
||||||
|
if(!Prcb->TimerRequest)
|
||||||
|
{
|
||||||
|
/* Register the timer expiration request and record a timer slot */
|
||||||
|
Prcb->TimerRequest = (ULONG_PTR)TrapFrame;
|
||||||
|
Prcb->TimerHand = TimerHand;
|
||||||
|
|
||||||
|
/* Request a DPC to safely retire the timer */
|
||||||
|
HL::Irq::SendSoftwareInterrupt(DISPATCH_LEVEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user