From d0c1e25256ccf7cde703bacd16eec04e55384551 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Sat, 4 Dec 1999 07:40:53 +0000 Subject: [PATCH] fixed timers and a wait functions, and a few bugs svn path=/trunk/; revision=818 --- reactos/ntoskrnl/ke/timer.c | 36 ++++++++++++++++++------------- reactos/ntoskrnl/ke/wait.c | 43 +++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index eba73cbb99f..cbbca427662 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -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 * PROJECT: ReactOS kernel @@ -7,6 +7,7 @@ * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * 28/05/98: Created + * 12/3/99: Phillip Susi: enabled the timers, fixed spin lock */ /* NOTES ******************************************************************/ @@ -74,6 +75,8 @@ volatile ULONGLONG KiTimerTicks; static LIST_ENTRY TimerListHead; static KSPIN_LOCK TimerListLock; +/* must raise IRQL to HIGH_LEVEL and grab spin lock there, to sync with ISR */ + extern ULONG PiNrRunnableThreads; #define MICROSECONDS_PER_TICK (54945) @@ -239,7 +242,8 @@ BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period, DPRINT("KeSetTimerEx(Timer %x)\n",Timer); - KeAcquireSpinLock(&TimerListLock,&oldlvl); + KeRaiseIrql( HIGH_LEVEL, &oldlvl ); + KeAcquireSpinLockAtDpcLevel(&TimerListLock); Timer->Dpc = Dpc; if (DueTime.QuadPart < 0) @@ -276,7 +280,8 @@ BOOLEAN KeCancelTimer(PKTIMER Timer) DPRINT("KeCancelTimer(Timer %x)\n",Timer); - KeAcquireSpinLock(&TimerListLock, &oldlvl); + KeRaiseIrql( HIGH_LEVEL, &oldlvl ); + KeAcquireSpinLockAtDpcLevel( &TimerListLock ); if (Timer->TimerListEntry.Flink == NULL) { @@ -381,13 +386,8 @@ VOID KeExpireTimers(VOID) PLIST_ENTRY current_entry = NULL; PKTIMER current = NULL; KIRQL oldlvl; - -// DPRINT("KeExpireTimers()\n"); - - if (TimerInitDone == FALSE) - { - return; - } + + DPRINT("KeExpireTimers()\n"); current_entry = TimerListHead.Flink; @@ -396,7 +396,8 @@ VOID KeExpireTimers(VOID) // DPRINT("current_entry->Flink %x\n",current_entry->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)) { @@ -410,7 +411,7 @@ VOID KeExpireTimers(VOID) } } - KeReleaseSpinLock(&TimerListLock,oldlvl); + KeReleaseSpinLock( &TimerListLock, oldlvl ); // DPRINT("Finished KeExpireTimers()\n"); } @@ -429,6 +430,10 @@ VOID KiTimerInterrupt(VOID) extern unsigned int EiUsedNonPagedPool; extern ULONG MiNrFreePages; + if (TimerInitDone == FALSE) + { + return; + } /* * Increment the number of timers ticks */ @@ -456,9 +461,9 @@ VOID KiTimerInterrupt(VOID) // sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks, // (unsigned int)EiFreeNonPagedPool); // sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool); -// sprintf(str,"%.8u %.8u",PiNrRunnableThreads,KiTimerTicks); - sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads, - (unsigned int)MiNrFreePages); + sprintf(str,"%.8u %.8u",(unsigned int)PiNrRunnableThreads,(unsigned int)KiTimerTicks); +// sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads, +// (unsigned int)MiNrFreePages); for (i=0;i<17;i++) { *vidmem=str[i]; @@ -466,6 +471,7 @@ VOID KiTimerInterrupt(VOID) *vidmem=0x7; vidmem++; } + KeExpireTimers(); } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index a2a0e42fd54..539db3dd6e9 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -6,6 +6,8 @@ * PROGRAMMER: David Welch (welch@mcmail.com) * REVISION HISTORY: * 21/07/98: Created + * 12/1/99: Phillip Susi: Fixed wake code in KeDispatcherObjectWake + * so that things like KeWaitForXXX() return the correct value */ /* NOTES ******************************************************************** @@ -134,14 +136,21 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) while (!IsListEmpty(&(hdr->WaitListHead))) { - current_entry = RemoveHeadList(&hdr->WaitListHead); - current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, + NTSTATUS Status = STATUS_WAIT_0; + current_entry = RemoveHeadList(&hdr->WaitListHead); + current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, WaitListEntry); DPRINT("Waking %x\n",current->Thread); if (current->WaitType == WaitAny) { 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; } else @@ -180,7 +189,7 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) KiSideEffectsBeforeWake(hdr); PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - NULL); + &Status); }; return(TRUE); } @@ -190,6 +199,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) PKWAIT_BLOCK current; PLIST_ENTRY current_entry; PKWAIT_BLOCK PrevBlock; + NTSTATUS Status = STATUS_WAIT_0; DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr); DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", @@ -207,7 +217,13 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) if (current->WaitType == WaitAny) { 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 { @@ -246,7 +262,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) KiSideEffectsBeforeWake(hdr); PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - NULL); + &Status); return(TRUE); } @@ -363,9 +379,9 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, blk.WaitKey = 0; blk.WaitType = WaitAny; 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)); -// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", -// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); KeReleaseDispatcherDatabaseLock(FALSE); DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, KeGetCurrentIrql()); @@ -387,9 +403,8 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, DPRINT("Current thread is alertable and APCs are pending\n"); return(STATUS_USER_APC); } - DPRINT("Returning from KeWaitForSingleObject()\n"); - return(Status); + return Status; } @@ -513,16 +528,6 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count, } 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); }