|
From: Genadi V. Z. <mg...@po...> - 2002-04-22 22:45:42
|
static VOID
HandleExpiredTimer(PKTIMER current, BOOLEAN Relative)
{
// ..............................
// ..............................
if (current->Period != 0)
{
if (Relative)
current->DueTime.QuadPart -= (LONGLONG) current->Period *
SYSTEM_TIME_UNITS_PER_MSEC;
else
current->DueTime.QuadPart += (LONGLONG) current->Period *
SYSTEM_TIME_UNITS_PER_MSEC;
}
// ..............................
// ..............................
}
VOID KeExpireTimers(VOID)
{
LARGE_INTEGER SystemTicks; /* this tick's time */
LARGE_INTEGER CurrentTime;
PLIST_ENTRY Entry;
PLIST_ENTRY Next;
KIRQL oldlvl;
KeQueryTickCount(& SystemTicks); /* for relative time. */
KeQuerySystemTime(& CurrentTime); /* for absolute time. */
KeRaiseIrql(HIGH_LEVEL, & oldlvl);
KeAcquireSpinLockAtDpcLevel(& TimerListLock);
for (Entry = TimerListHead.Flink; Entry != & TimerListHead; Entry = Next)
{
PKTIMER Timer = CONTAINING_RECORD(Entry, KTIMER, TimerListEntry);
const PLARGE_INTEGER pDueTime = (PLARGE_INTEGER) & Timer->DueTime;
Next = Entry->Flink;
if (RtlLargeIntegerLessThanZero(* pDueTime))
{
/* relative due time */
if (RtlLargeIntegerLessThanZero(RtlLargeIntegerAdd(SystemTicks, *
pDueTime)))
continue;
/* work with expired timer object */
HandleExpiredTimer(Timer, TRUE);
}
else
{
/* absolute due time */
if (RtlLargeIntegerLessThan(CurrentTime, * pDueTime))
continue;
/* work with expired timer object */
HandleExpiredTimer(Timer, FALSE);
}
}
KeReleaseSpinLock(& TimerListLock, oldlvl);
}
NTKERNELAPI
BOOLEAN
KeSetTimerEx(
IN PKTIMER Timer,
IN LARGE_INTEGER DueTime,
IN LONG Period OPTIONAL, /* milliseconds */
IN PKDPC Dpc OPTIONAL
)
{
KIRQL oldlvl;
//DPRINT("KeSetTimerEx(Timer %x), DueTime: \n",Timer);
KeAcquireSpinLock(& TimerListLock, & oldlvl);
Timer->Dpc = Dpc;
#if 1
Timer->DueTime.QuadPart = DueTime.QuadPart;
#else
// todo: need handling system time ajusting.
if (DueTime.QuadPart < 0)
{
LARGE_INTEGER SystemTime; /* this tick's time */
KeQuerySystemTime(& SystemTime);
Timer->DueTime.QuadPart = SystemTime.QuadPart - DueTime.QuadPart;
}
else
Timer->DueTime.QuadPart = DueTime.QuadPart;
#endif
Timer->Period = Period;
Timer->Header.SignalState = FALSE;
if (! IsListEmpty(& Timer->TimerListEntry))
{
KeReleaseSpinLock(&TimerListLock, oldlvl);
return TRUE;
}
InsertTailList(& TimerListHead, & Timer->TimerListEntry);
KeReleaseSpinLock(& TimerListLock, oldlvl);
return FALSE;
}
|