Author: ion Date: Tue Jan 16 04:27:36 2007 New Revision: 25479
URL: http://svn.reactos.org/svn/reactos?rev=25479&view=rev Log: - Fix insertion of special APC into APC delivery list. - Re-identize some APC code (just formatting change). - Detect APC during GateWait. Previous check scanned for DeferredReady, which is incorrect. - Simplfy KeremovequeueApc to take advantage of the fact RemoveEntryList now returns whether the list is empty or not.
Modified: trunk/reactos/ntoskrnl/ex/timer.c trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ex/timer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/timer.c?rev=254... ============================================================================== --- trunk/reactos/ntoskrnl/ex/timer.c (original) +++ trunk/reactos/ntoskrnl/ex/timer.c Tue Jan 16 04:27:36 2007 @@ -280,7 +280,7 @@ PreviousMode, (PVOID*)&Timer, NULL); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Lock the Timer */ KeAcquireSpinLock(&Timer->Lock, &OldIrql); @@ -289,7 +289,9 @@ if (Timer->ApcAssociated) { /* Get the Thread. */ - TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread, ETHREAD, Tcb); + TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread, + ETHREAD, + Tcb);
/* Lock its active list */ KeAcquireSpinLockAtDpcLevel(&TimerThread->ActiveTimerListLock); @@ -403,7 +405,7 @@ 0, 0, (PVOID*)&Timer); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Initialize the DPC */ KeInitializeDpc(&Timer->TimerDpc, ExpTimerDpcRoutine, Timer); @@ -475,7 +477,7 @@ DesiredAccess, NULL, &hTimer); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Make sure it's safe to write to the handle */ _SEH_TRY @@ -531,14 +533,15 @@ _SEH_TRY { /* Return the remaining time, corrected */ - BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart - + BasicInfo->TimeRemaining.QuadPart = Timer-> + KeTimer.DueTime.QuadPart - KeQueryInterruptTime();
/* Return the current state */ BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
/* Return the buffer length if requested */ - if(ReturnLength) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION); + if (ReturnLength) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION); } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
Modified: trunk/reactos/ntoskrnl/ke/apc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/apc.c?rev=25479... ============================================================================== --- trunk/reactos/ntoskrnl/ke/apc.c (original) +++ trunk/reactos/ntoskrnl/ke/apc.c Tue Jan 16 04:27:36 2007 @@ -8,6 +8,7 @@
/* INCLUDES *****************************************************************/
+#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> @@ -89,7 +90,7 @@ PLIST_ENTRY ListHead, NextEntry; PKAPC QueuedApc; NTSTATUS Status; - BOOLEAN RequestInterrupt; + BOOLEAN RequestInterrupt = FALSE;
/* * Check if the caller wanted this APC to use the thread's environment at @@ -137,8 +138,8 @@ { /* Special APC, find the first Normal APC in the list */ ListHead = &ApcState->ApcListHead[ApcMode]; - NextEntry = ListHead->Flink; - while(NextEntry != ListHead) + NextEntry = ListHead->Blink; + while (NextEntry != ListHead) { /* Get the APC */ QueuedApc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry); @@ -147,11 +148,8 @@ if (QueuedApc->NormalRoutine) break;
/* Move to the next APC in the Queue */ - NextEntry = NextEntry->Flink; - } - - /* Move to the APC before this one (ie: the last Special APC) */ - NextEntry = NextEntry->Blink; + NextEntry = NextEntry->Blink; + }
/* Insert us here */ InsertHeadList(NextEntry, &Apc->ApcListEntry); @@ -185,23 +183,8 @@ /* Acquire the dispatcher lock */ KiAcquireDispatcherLock();
- /* Check if this is a non-kernel mode APC */ - if (ApcMode != KernelMode) - { - /* - * Not a Kernel-Mode APC. Are we waiting in user-mode? - * If so, then are we alertable or already have an APC pending? - */ - if (((Thread->State == Waiting) && (Thread->WaitMode == UserMode)) && - ((Thread->Alertable) || (Thread->ApcState.UserApcPending))) - { - /* Set user-mode APC pending */ - Thread->ApcState.UserApcPending = TRUE; - Status = STATUS_USER_APC; - goto Unwait; - } - } - else + /* Check if this is a kernel-mode APC */ + if (ApcMode == KernelMode) { /* Kernel-mode APC, set us pending */ Thread->ApcState.KernelApcPending = TRUE; @@ -211,45 +194,37 @@ { /* The thread is running, so remember to send a request */ RequestInterrupt = TRUE; -#ifndef CONFIG_SMP - /* On UP systems, request it immediately */ - HalRequestSoftwareInterrupt(APC_LEVEL); -#endif } - else + else if ((Thread->State == Waiting) && + (Thread->WaitIrql == PASSIVE_LEVEL) && + !(Thread->SpecialApcDisable) && + (!(Apc->NormalRoutine) || + (!(Thread->KernelApcDisable) && + !(Thread->ApcState.KernelApcInProgress)))) { - /* - * If the thread is Waiting at PASSIVE_LEVEL AND - * Special APCs are not disabled AND - * He is a Normal APC AND - * Kernel APCs are not disabled AND - * Kernel APC is not pending OR - * He is a Special APC THEN - * Unwait thread with STATUS_KERNEL_APC - */ - if ((Thread->State == Waiting) && - (Thread->WaitIrql == PASSIVE_LEVEL) && - !(Thread->SpecialApcDisable) && - (!(Apc->NormalRoutine) || - (!(Thread->KernelApcDisable) && - !(Thread->ApcState.KernelApcInProgress)))) - { - /* We'll unwait with this status */ - Status = STATUS_KERNEL_APC; - - /* Wake up the thread */ + /* We'll unwait with this status */ + Status = STATUS_KERNEL_APC; + + /* Wake up the thread */ Unwait: - KiUnwaitThread(Thread, Status, PriorityBoost); - } - else - { - /* Check if the thread is in a deferred ready state */ - if (Thread->State == DeferredReady) - { - /* FIXME: TODO in new scheduler */ - } - } + KiUnwaitThread(Thread, Status, PriorityBoost); } + else if (Thread->State == GateWait) + { + /* We were in a gate wait. FIXME: Handle this */ + DPRINT1("Not yet supported -- Report this to Alex\n"); + KEBUGCHECK(0); + } + } + else if ((Thread->State == Waiting) && + (Thread->WaitMode == UserMode) && + ((Thread->Alertable) || + (Thread->ApcState.UserApcPending))) + { + /* Set user-mode APC pending */ + Thread->ApcState.UserApcPending = TRUE; + Status = STATUS_USER_APC; + goto Unwait; }
/* Release dispatcher lock */ @@ -891,10 +866,7 @@
/* Acquire the dispatcher lock and remove it from the list */ KiAcquireDispatcherLockAtDpcLevel(); - RemoveEntryList(&Apc->ApcListEntry); - - /* If the Queue is completely empty, then no more APCs are pending */ - if (IsListEmpty(&ApcState->ApcListHead[Apc->ApcMode])) + if (RemoveEntryList(&ApcState->ApcListHead[Apc->ApcMode])) { /* Set the correct state based on the APC Mode */ if (Apc->ApcMode == KernelMode)