fixed timers and a wait functions, and a few bugs

svn path=/trunk/; revision=818
This commit is contained in:
Phillip Susi 1999-12-04 07:40:53 +00:00
parent d4c340c696
commit d0c1e25256
2 changed files with 45 additions and 34 deletions

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.21 1999/11/24 11:51:50 dwelch Exp $ /* $Id: timer.c,v 1.22 1999/12/04 07:40:53 phreak Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -7,6 +7,7 @@
* PROGRAMMER: David Welch (welch@mcmail.com) * PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY: * UPDATE HISTORY:
* 28/05/98: Created * 28/05/98: Created
* 12/3/99: Phillip Susi: enabled the timers, fixed spin lock
*/ */
/* NOTES ******************************************************************/ /* NOTES ******************************************************************/
@ -74,6 +75,8 @@ volatile ULONGLONG KiTimerTicks;
static LIST_ENTRY TimerListHead; static LIST_ENTRY TimerListHead;
static KSPIN_LOCK TimerListLock; static KSPIN_LOCK TimerListLock;
/* must raise IRQL to HIGH_LEVEL and grab spin lock there, to sync with ISR */
extern ULONG PiNrRunnableThreads; extern ULONG PiNrRunnableThreads;
#define MICROSECONDS_PER_TICK (54945) #define MICROSECONDS_PER_TICK (54945)
@ -239,7 +242,8 @@ BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period,
DPRINT("KeSetTimerEx(Timer %x)\n",Timer); DPRINT("KeSetTimerEx(Timer %x)\n",Timer);
KeAcquireSpinLock(&TimerListLock,&oldlvl); KeRaiseIrql( HIGH_LEVEL, &oldlvl );
KeAcquireSpinLockAtDpcLevel(&TimerListLock);
Timer->Dpc = Dpc; Timer->Dpc = Dpc;
if (DueTime.QuadPart < 0) if (DueTime.QuadPart < 0)
@ -276,7 +280,8 @@ BOOLEAN KeCancelTimer(PKTIMER Timer)
DPRINT("KeCancelTimer(Timer %x)\n",Timer); DPRINT("KeCancelTimer(Timer %x)\n",Timer);
KeAcquireSpinLock(&TimerListLock, &oldlvl); KeRaiseIrql( HIGH_LEVEL, &oldlvl );
KeAcquireSpinLockAtDpcLevel( &TimerListLock );
if (Timer->TimerListEntry.Flink == NULL) if (Timer->TimerListEntry.Flink == NULL)
{ {
@ -381,13 +386,8 @@ VOID KeExpireTimers(VOID)
PLIST_ENTRY current_entry = NULL; PLIST_ENTRY current_entry = NULL;
PKTIMER current = NULL; PKTIMER current = NULL;
KIRQL oldlvl; KIRQL oldlvl;
// DPRINT("KeExpireTimers()\n"); DPRINT("KeExpireTimers()\n");
if (TimerInitDone == FALSE)
{
return;
}
current_entry = TimerListHead.Flink; current_entry = TimerListHead.Flink;
@ -396,7 +396,8 @@ VOID KeExpireTimers(VOID)
// DPRINT("current_entry->Flink %x\n",current_entry->Flink); // DPRINT("current_entry->Flink %x\n",current_entry->Flink);
// DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink); // DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink);
KeAcquireSpinLock(&TimerListLock, &oldlvl); KeRaiseIrql( HIGH_LEVEL, &oldlvl );
KeAcquireSpinLockAtDpcLevel(&TimerListLock);
while (current_entry!=(&TimerListHead)) while (current_entry!=(&TimerListHead))
{ {
@ -410,7 +411,7 @@ VOID KeExpireTimers(VOID)
} }
} }
KeReleaseSpinLock(&TimerListLock,oldlvl); KeReleaseSpinLock( &TimerListLock, oldlvl );
// DPRINT("Finished KeExpireTimers()\n"); // DPRINT("Finished KeExpireTimers()\n");
} }
@ -429,6 +430,10 @@ VOID KiTimerInterrupt(VOID)
extern unsigned int EiUsedNonPagedPool; extern unsigned int EiUsedNonPagedPool;
extern ULONG MiNrFreePages; extern ULONG MiNrFreePages;
if (TimerInitDone == FALSE)
{
return;
}
/* /*
* Increment the number of timers ticks * Increment the number of timers ticks
*/ */
@ -456,9 +461,9 @@ VOID KiTimerInterrupt(VOID)
// sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks, // sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks,
// (unsigned int)EiFreeNonPagedPool); // (unsigned int)EiFreeNonPagedPool);
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool); // sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
// sprintf(str,"%.8u %.8u",PiNrRunnableThreads,KiTimerTicks); sprintf(str,"%.8u %.8u",(unsigned int)PiNrRunnableThreads,(unsigned int)KiTimerTicks);
sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads, // sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads,
(unsigned int)MiNrFreePages); // (unsigned int)MiNrFreePages);
for (i=0;i<17;i++) for (i=0;i<17;i++)
{ {
*vidmem=str[i]; *vidmem=str[i];
@ -466,6 +471,7 @@ VOID KiTimerInterrupt(VOID)
*vidmem=0x7; *vidmem=0x7;
vidmem++; vidmem++;
} }
KeExpireTimers();
} }

View file

@ -6,6 +6,8 @@
* PROGRAMMER: David Welch (welch@mcmail.com) * PROGRAMMER: David Welch (welch@mcmail.com)
* REVISION HISTORY: * REVISION HISTORY:
* 21/07/98: Created * 21/07/98: Created
* 12/1/99: Phillip Susi: Fixed wake code in KeDispatcherObjectWake
* so that things like KeWaitForXXX() return the correct value
*/ */
/* NOTES ******************************************************************** /* NOTES ********************************************************************
@ -134,14 +136,21 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
while (!IsListEmpty(&(hdr->WaitListHead))) while (!IsListEmpty(&(hdr->WaitListHead)))
{ {
current_entry = RemoveHeadList(&hdr->WaitListHead); NTSTATUS Status = STATUS_WAIT_0;
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, current_entry = RemoveHeadList(&hdr->WaitListHead);
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
WaitListEntry); WaitListEntry);
DPRINT("Waking %x\n",current->Thread); DPRINT("Waking %x\n",current->Thread);
if (current->WaitType == WaitAny) if (current->WaitType == WaitAny)
{ {
DPRINT("WaitAny: Remove all wait blocks.\n"); DPRINT("WaitAny: Remove all wait blocks.\n");
//count the number of the wait block that is waking us, and set that as the wake status
for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock )
if( PrevBlock == current )
break;
if( PrevBlock == 0 )
DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" );
current->Thread->WaitBlockList = NULL; current->Thread->WaitBlockList = NULL;
} }
else else
@ -180,7 +189,7 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
KiSideEffectsBeforeWake(hdr); KiSideEffectsBeforeWake(hdr);
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
NULL); &Status);
}; };
return(TRUE); return(TRUE);
} }
@ -190,6 +199,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
PKWAIT_BLOCK current; PKWAIT_BLOCK current;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PKWAIT_BLOCK PrevBlock; PKWAIT_BLOCK PrevBlock;
NTSTATUS Status = STATUS_WAIT_0;
DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr); DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr);
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
@ -207,7 +217,13 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
if (current->WaitType == WaitAny) if (current->WaitType == WaitAny)
{ {
DPRINT("WaitAny: Remove all wait blocks.\n"); DPRINT("WaitAny: Remove all wait blocks.\n");
current->Thread->WaitBlockList = NULL; //count the number of the wait block that is waking us, and set that as the wake status
for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock )
if( PrevBlock == current )
break;
if( PrevBlock == 0 )
DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" );
current->Thread->WaitBlockList = NULL;
} }
else else
{ {
@ -246,7 +262,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
KiSideEffectsBeforeWake(hdr); KiSideEffectsBeforeWake(hdr);
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
NULL); &Status);
return(TRUE); return(TRUE);
} }
@ -363,9 +379,9 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
blk.WaitKey = 0; blk.WaitKey = 0;
blk.WaitType = WaitAny; blk.WaitType = WaitAny;
blk.NextWaitBlock = NULL; blk.NextWaitBlock = NULL;
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x blk.WaitListEntry = %x\n",
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, blk.WaitListEntry );
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(FALSE);
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
KeGetCurrentIrql()); KeGetCurrentIrql());
@ -387,9 +403,8 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
DPRINT("Current thread is alertable and APCs are pending\n"); DPRINT("Current thread is alertable and APCs are pending\n");
return(STATUS_USER_APC); return(STATUS_USER_APC);
} }
DPRINT("Returning from KeWaitForSingleObject()\n"); DPRINT("Returning from KeWaitForSingleObject()\n");
return(Status); return Status;
} }
@ -513,16 +528,6 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
} }
DPRINT("Returning from KeWaitForMultipleObjects()\n"); DPRINT("Returning from KeWaitForMultipleObjects()\n");
if (WaitType == WaitAny)
{
for (i = 0; i < Count; i++)
{
if (((DISPATCHER_HEADER *)Object[i])->SignalState)
return(STATUS_WAIT_0+i);
}
}
return(Status); return(Status);
} }