/*
* Current time
*/
-static unsigned long long boot_time = 0;
-static unsigned long long system_time = 0;
+static LARGE_INTEGER boot_time = (LARGE_INTEGER)0LL;
+static LARGE_INTEGER system_time = (LARGE_INTEGER)0LL;
/*
* Number of timer interrupts since initialisation
*/
static LIST_ENTRY TimerListHead;
static KSPIN_LOCK TimerListLock;
+static KSPIN_LOCK TimerValueLock;
static KDPC ExpireTimerDpc;
-/* must raise IRQL to HIGH_LEVEL and grab spin lock there, to sync with ISR */
+/* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */
extern ULONG PiNrRunnableThreads;
NtQueryPerformanceCounter(IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency)
{
- UNIMPLEMENTED;
+ LARGE_INTEGER PerfCounter;
+ LARGE_INTEGER PerfFrequency;
+
+ PerfCounter = KeQueryPerformanceCounter(&PerfFrequency);
+
+ if (Counter != NULL)
+ Counter->QuadPart = PerfCounter.QuadPart;
+
+ if (Frequency != NULL)
+ Frequency->QuadPart = PerfFrequency.QuadPart;
+
+ return(STATUS_SUCCESS);
}
* 1st of January, 1601.
*/
{
- CurrentTime->QuadPart = system_time;
+ KIRQL oldIrql;
+
+ KeRaiseIrql(PROFILE_LEVEL, &oldIrql);
+ KeAcquireSpinLockAtDpcLevel(&TimerValueLock);
+ *CurrentTime = system_time;
+ KeReleaseSpinLock(&TimerValueLock, oldIrql);
}
*/
{
KIRQL oldlvl;
+ LARGE_INTEGER SystemTime;
DPRINT("KeSetTimerEx(Timer %x), DueTime: \n",Timer);
- KeAcquireSpinLock( &TimerListLock, &oldlvl );
-
+
+ KeRaiseIrql(PROFILE_LEVEL, &oldlvl);
+ KeAcquireSpinLockAtDpcLevel(&TimerValueLock);
+
+ SystemTime = system_time;
+
+ KeReleaseSpinLock(&TimerValueLock, DISPATCH_LEVEL);
+ KeAcquireSpinLockAtDpcLevel(&TimerListLock);
+
Timer->Dpc = Dpc;
if (DueTime.QuadPart < 0)
{
- Timer->DueTime.QuadPart = system_time - DueTime.QuadPart;
+
+ Timer->DueTime.QuadPart = SystemTime.QuadPart - DueTime.QuadPart;
}
else
{
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
- KeRaiseIrql(HIGH_LEVEL, &oldlvl);
- KeAcquireSpinLockAtDpcLevel( &TimerListLock );
+ KeAcquireSpinLock(&TimerListLock, &oldlvl);
if (Timer->TimerListEntry.Flink == NULL)
{
PLIST_ENTRY current_entry = NULL;
PKTIMER current = NULL;
ULONG Eip = (ULONG)Arg1;
+ KIRQL oldIrql;
+ LARGE_INTEGER SystemTime;
DPRINT("KeExpireTimers()\n");
-
- current_entry = TimerListHead.Flink;
-
+
+ KeRaiseIrql(PROFILE_LEVEL, &oldIrql);
+ KeAcquireSpinLockAtDpcLevel(&TimerValueLock);
+
+ SystemTime = system_time;
+
+ KeReleaseSpinLock(&TimerValueLock, oldIrql);
KeAcquireSpinLockAtDpcLevel(&TimerListLock);
-
+
+ if (KeGetCurrentIrql() > DISPATCH_LEVEL)
+ {
+ DPRINT1("-----------------------------\n");
+ KeBugCheck(0);
+ }
+
+
+ current_entry = TimerListHead.Flink;
+
while (current_entry != &TimerListHead)
{
current = CONTAINING_RECORD(current_entry, KTIMER, TimerListEntry);
current_entry = current_entry->Flink;
-
- if (system_time >= current->DueTime.QuadPart)
+ if ((ULONGLONG) SystemTime.QuadPart >= current->DueTime.QuadPart)
{
HandleExpiredTimer(current);
}
* FUNCTION: Handles a timer interrupt
*/
{
+
+ assert(KeGetCurrentIrql() == PROFILE_LEVEL);
+
KiRawTicks++;
if (TimerInitDone == FALSE)
*/
KeTickCount++;
SharedUserData->TickCountLow++;
- system_time = system_time + CLOCK_INCREMENT;
+
+ KeAcquireSpinLockAtDpcLevel(&TimerValueLock);
+ system_time.QuadPart += CLOCK_INCREMENT;
+ KeReleaseSpinLockFromDpcLevel(&TimerValueLock);
/*
* Queue a DPC that will expire timers
DPRINT("KeInitializeTimerImpl()\n");
InitializeListHead(&TimerListHead);
KeInitializeSpinLock(&TimerListLock);
+ KeInitializeSpinLock(&TimerValueLock);
KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0);
TimerInitDone = TRUE;
/*
*/
HalQueryRealTimeClock(&TimeFields);
RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
- boot_time=SystemBootTime.QuadPart;
+ boot_time=SystemBootTime;
system_time=boot_time;
DPRINT("Finished KeInitializeTimerImpl()\n");