/*
* 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
#endif /* LIBCAPTIVE */
static KSPIN_LOCK TimerListLock;
#ifndef LIBCAPTIVE
+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);
}
}
+/*
+ * @implemented
+ */
NTSTATUS STDCALL
KeDelayExecutionThread (KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
}
+/*
+ * @implemented
+ */
ULONG STDCALL
KeQueryTimeIncrement(VOID)
/*
}
+/*
+ * @implemented
+ */
VOID STDCALL
KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
/*
* 1st of January, 1601.
*/
{
- CurrentTime->QuadPart = system_time;
+ KIRQL oldIrql;
+
+ KeRaiseIrql(PROFILE_LEVEL, &oldIrql);
+ KeAcquireSpinLockAtDpcLevel(&TimerValueLock);
+ *CurrentTime = system_time;
+ KeReleaseSpinLock(&TimerValueLock, oldIrql);
}
}
+/*
+ * @implemented
+ */
BOOLEAN STDCALL
KeSetTimer (PKTIMER Timer,
LARGE_INTEGER DueTime,
return(KeSetTimerEx(Timer, DueTime, 0, Dpc));
}
+/*
+ * @implemented
+ */
BOOLEAN STDCALL
KeSetTimerEx (PKTIMER Timer,
LARGE_INTEGER DueTime,
*/
{
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
{
#endif /* LIBCAPTIVE */
+/*
+ * @implemented
+ */
BOOLEAN STDCALL
KeCancelTimer (PKTIMER Timer)
/*
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
- KeRaiseIrql(HIGH_LEVEL, &oldlvl);
- KeAcquireSpinLockAtDpcLevel( &TimerListLock );
+ KeAcquireSpinLock(&TimerListLock, &oldlvl);
if (Timer->TimerListEntry.Flink == NULL)
{
#ifndef LIBCAPTIVE
+/*
+ * @implemented
+ */
BOOLEAN STDCALL
KeReadStateTimer (PKTIMER Timer)
{
#endif /* LIBCAPTIVE */
+/*
+ * @implemented
+ */
VOID STDCALL
KeInitializeTimer (PKTIMER Timer)
/*
KeInitializeTimerEx(Timer, NotificationTimer);
}
+/*
+ * @implemented
+ */
VOID STDCALL
KeInitializeTimerEx (PKTIMER Timer,
TIMER_TYPE Type)
#ifndef LIBCAPTIVE
+/*
+ * @implemented
+ */
VOID STDCALL
KeQueryTickCount(PLARGE_INTEGER TickCount)
/*
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;
+ SharedUserData->TickCountLow = 0;
+ SharedUserData->TickCountMultiplier = 167783691; // 2^24 * 1193182 / 119310
+
DPRINT("Finished KeInitializeTimerImpl()\n");
}