mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Protected the access to system_time with a spinlock.
svn path=/trunk/; revision=3860
This commit is contained in:
parent
d008835685
commit
e1b39fac3c
1 changed files with 52 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.53 2002/09/08 10:23:29 chorns Exp $
|
||||
/* $Id: timer.c,v 1.54 2002/12/09 20:15:25 hbirr Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -35,8 +35,8 @@
|
|||
/*
|
||||
* 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
|
||||
|
@ -58,6 +58,7 @@ volatile ULONG KiRawTicks = 0;
|
|||
*/
|
||||
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 */
|
||||
|
@ -166,7 +167,12 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -221,14 +227,23 @@ KeSetTimerEx (PKTIMER Timer,
|
|||
*/
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -261,8 +276,7 @@ KeCancelTimer (PKTIMER Timer)
|
|||
|
||||
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
|
||||
KeAcquireSpinLockAtDpcLevel( &TimerListLock );
|
||||
KeAcquireSpinLock(&TimerListLock, &oldlvl);
|
||||
|
||||
if (Timer->TimerListEntry.Flink == NULL)
|
||||
{
|
||||
|
@ -380,20 +394,34 @@ KeExpireTimers(PKDPC Dpc,
|
|||
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 (SystemTime.QuadPart >= current->DueTime.QuadPart)
|
||||
{
|
||||
HandleExpiredTimer(current);
|
||||
}
|
||||
|
@ -412,6 +440,9 @@ KiUpdateSystemTime(KIRQL oldIrql,
|
|||
* FUNCTION: Handles a timer interrupt
|
||||
*/
|
||||
{
|
||||
|
||||
assert(KeGetCurrentIrql() == PROFILE_LEVEL);
|
||||
|
||||
KiRawTicks++;
|
||||
|
||||
if (TimerInitDone == FALSE)
|
||||
|
@ -423,7 +454,10 @@ KiUpdateSystemTime(KIRQL oldIrql,
|
|||
*/
|
||||
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
|
||||
|
@ -445,6 +479,7 @@ KeInitializeTimerImpl(VOID)
|
|||
DPRINT("KeInitializeTimerImpl()\n");
|
||||
InitializeListHead(&TimerListHead);
|
||||
KeInitializeSpinLock(&TimerListLock);
|
||||
KeInitializeSpinLock(&TimerValueLock);
|
||||
KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0);
|
||||
TimerInitDone = TRUE;
|
||||
/*
|
||||
|
@ -452,7 +487,7 @@ KeInitializeTimerImpl(VOID)
|
|||
*/
|
||||
HalQueryRealTimeClock(&TimeFields);
|
||||
RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
|
||||
boot_time=SystemBootTime.QuadPart;
|
||||
boot_time=SystemBootTime;
|
||||
system_time=boot_time;
|
||||
|
||||
DPRINT("Finished KeInitializeTimerImpl()\n");
|
||||
|
|
Loading…
Reference in a new issue