From b424efdf6b56c01de0826a54d278d4c6143eaf21 Mon Sep 17 00:00:00 2001 From: Gunnar Dalsnes Date: Sun, 21 Nov 2004 18:42:58 +0000 Subject: [PATCH] kill.c: remove useless call to KeRemoveAllWaitsThread + misc usecall.c: fix apc delivery debug.c: add irql asserts svn path=/trunk/; revision=11759 --- reactos/ntoskrnl/include/internal/debug.h | 5 ++++- reactos/ntoskrnl/include/internal/ke.h | 6 ++++-- reactos/ntoskrnl/ke/i386/usercall.c | 24 +++++++++++++++-------- reactos/ntoskrnl/ps/kill.c | 18 ++++++++++------- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/debug.h b/reactos/ntoskrnl/include/internal/debug.h index 541169f0f66..4e0df358ee1 100644 --- a/reactos/ntoskrnl/include/internal/debug.h +++ b/reactos/ntoskrnl/include/internal/debug.h @@ -124,7 +124,10 @@ * ARGUMENTS: * x = Maximum irql */ -#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql()<=(x)) +#define ASSERT_IRQL_LESS_OR_EQUAL(x) ASSERT(KeGetCurrentIrql()<=(x)) +#define ASSERT_IRQL(x) ASSERT_IRQL_LESS_OR_EQUAL(x) +#define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql()==(x)) +#define ASSERT_IRQL_LESS(x) ASSERT(KeGetCurrentIrql()<(x)) #define assert_irql(x) assert(KeGetCurrentIrql()<=(x)) #endif /* __INTERNAL_DEBUG */ diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index f128cf1b48d..7f344687efd 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -72,7 +72,7 @@ VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID); VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql); VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID); -BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); +BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr); VOID STDCALL KeExpireTimers(PKDPC Apc, PVOID Arg1, PVOID Arg2, @@ -81,7 +81,9 @@ VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type, ULONG Size, ULONG SignalState); VOID KeDumpStackFrames(PULONG Frame); BOOLEAN KiTestAlert(VOID); -VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus, BOOL Unblock); + +BOOLEAN KiAbortWaitThread(struct _KTHREAD* Thread, NTSTATUS WaitStatus); + PULONG KeGetStackTopThread(struct _ETHREAD* Thread); VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame); VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode, diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index 589baa01e49..7cac0ac905e 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -1,4 +1,4 @@ -/* $Id: usercall.c,v 1.31 2004/11/10 02:51:00 ion Exp $ +/* $Id: usercall.c,v 1.32 2004/11/21 18:42:58 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -41,14 +41,22 @@ KiSystemCallHook(ULONG Nr, ...) VOID KiAfterSystemCallHook(PKTRAP_FRAME TrapFrame) { - if (KeGetCurrentThread()->Alerted[1] != 0 && TrapFrame->Cs != KERNEL_CS) - { - KiDeliverApc(KernelMode, NULL, NULL); - } - if (KeGetCurrentThread()->Alerted[0] != 0 && TrapFrame->Cs != KERNEL_CS) - { + KIRQL oldIrql; + + /* If we are returning to umode, deliver one pending umode apc. + * Note that kmode apcs are also delivered, even if deliverymode is UserMode. + * This is because we can't return to umode with pending kmode apcs! + * FIXME: Should we deliver pending kmode apcs when returning from a + * kmode-to-kmode syscall (ZwXxx calls)????? + * -Gunnar + */ + if (TrapFrame->Cs != KERNEL_CS) + { + KeRaiseIrql(APC_LEVEL, &oldIrql); KiDeliverApc(UserMode, NULL, TrapFrame); - } + KeLowerIrql(oldIrql); + } + } diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index caa5e33d76b..feabafb8581 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -1,4 +1,4 @@ -/* $Id: kill.c,v 1.85 2004/11/20 23:46:37 blight Exp $ +/* $Id: kill.c,v 1.86 2004/11/21 18:42:58 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -133,6 +133,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) DPRINT("terminating %x\n",CurrentThread); + CurrentThread->HasTerminated = TRUE; CurrentThread->ExitStatus = ExitStatus; KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime); KeCancelTimer(&CurrentThread->Tcb.Timer); @@ -192,7 +193,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) oldIrql = KeAcquireDispatcherDatabaseLock(); CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; - KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); + KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); KeReleaseDispatcherDatabaseLock (oldIrql); /* The last thread shall close the door on exit */ @@ -211,8 +212,9 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) #ifdef _ENABLE_THRDEVTPAIR ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */ #endif /* _ENABLE_THRDEVTPAIR */ - KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE); + ASSERT(CurrentThread->Tcb.WaitBlockList == NULL); + PsDispatchThreadNoLock(THREAD_STATE_TERMINATED_1); DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread()); KEBUGCHECK(0); @@ -251,7 +253,7 @@ PsTerminateOtherThread(PETHREAD Thread, */ { PKAPC Apc; - NTSTATUS Status; + KIRQL OldIrql; DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n", Thread, ExitStatus); @@ -271,12 +273,14 @@ PsTerminateOtherThread(PETHREAD Thread, NULL, NULL, IO_NO_INCREMENT); + + OldIrql = KeAcquireDispatcherDatabaseLock(); if (THREAD_STATE_BLOCKED == Thread->Tcb.State && UserMode == Thread->Tcb.WaitMode) { DPRINT("Unblocking thread\n"); - Status = STATUS_THREAD_IS_TERMINATING; - KeRemoveAllWaitsThread(Thread, Status, TRUE); + KiAbortWaitThread((PKTHREAD)Thread, STATUS_THREAD_IS_TERMINATING); } + KeReleaseDispatcherDatabaseLock(OldIrql); } NTSTATUS STDCALL @@ -310,7 +314,7 @@ PiTerminateProcess(PEPROCESS Process, } OldIrql = KeAcquireDispatcherDatabaseLock (); Process->Pcb.DispatcherHeader.SignalState = TRUE; - KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader); + KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader); KeReleaseDispatcherDatabaseLock (OldIrql); ObDereferenceObject(Process); return(STATUS_SUCCESS);