From f822a2a9d949cfe4b488d3e6b3731dbce174213c Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 12 Dec 1999 00:59:39 +0000 Subject: [PATCH] Backed out Philip Susi's changes for further testing Returned kernel to working state. Made exception handling more tolerant svn path=/trunk/; revision=862 --- reactos/ntoskrnl/hal/x86/irql.c | 43 ++++++------ reactos/ntoskrnl/ke/apc.c | 116 +++++++++++++++++--------------- reactos/ntoskrnl/ke/apchelp.c | 3 + reactos/ntoskrnl/ke/i386/exp.c | 4 +- reactos/ntoskrnl/mm/mm.c | 5 ++ reactos/ntoskrnl/ob/object.c | 2 +- reactos/ntoskrnl/ps/psmgr.c | 2 +- reactos/ntoskrnl/ps/thread.c | 49 ++++++++++---- 8 files changed, 132 insertions(+), 92 deletions(-) diff --git a/reactos/ntoskrnl/hal/x86/irql.c b/reactos/ntoskrnl/hal/x86/irql.c index bce36232a18..5f4c654abc6 100644 --- a/reactos/ntoskrnl/hal/x86/irql.c +++ b/reactos/ntoskrnl/hal/x86/irql.c @@ -85,28 +85,29 @@ static VOID HiSwitchIrql(KIRQL oldIrql) __asm__("sti\n\t"); return; } - HiSetCurrentPICMask(0); - if(CurrentIrql == APC_LEVEL) - { - if (DpcQueueSize > 0 ) - { - KeSetCurrentIrql(DISPATCH_LEVEL); - __asm__("sti\n\t"); - KeDrainDpcQueue(); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - } - __asm__("sti\n\t"); - return; - } - if( CurrentIrql == PASSIVE_LEVEL && CurrentThread && CurrentThread->ApcState.KernelApcPending ) - { - KeSetCurrentIrql( APC_LEVEL ); - KeApcProlog2(); - KeSetCurrentIrql( PASSIVE_LEVEL ); - } - +<<<<<<< irql.c + + HiSetCurrentPICMask(0); + if(CurrentIrql == APC_LEVEL) + { + KeSetCurrentIrql(DISPATCH_LEVEL); + __asm__("sti\n\t"); + KeDrainDpcQueue(); + KeSetCurrentIrql(PASSIVE_LEVEL); + return; + } + + KeSetCurrentIrql(DISPATCH_LEVEL); __asm__("sti\n\t"); + KeDrainDpcQueue(); + if (CurrentIrql == PASSIVE_LEVEL && + CurrentThread != NULL && + CurrentThread->ApcState.KernelApcPending ) + { + KeSetCurrentIrql( APC_LEVEL ); +// KeApcProlog2(); + } + KeSetCurrentIrql(PASSIVE_LEVEL); } VOID KeSetCurrentIrql(KIRQL newlvl) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 239a071cd81..9520d47d476 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -6,7 +6,6 @@ * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 - * 12/11/99: Phillip Susi: Reworked the APC code */ /* INCLUDES *****************************************************************/ @@ -21,7 +20,7 @@ #include extern VOID KeApcProlog(VOID); -static KSPIN_LOCK PiApcLock; +extern KSPIN_LOCK PiThreadListLock; /* PROTOTYPES ****************************************************************/ @@ -42,15 +41,13 @@ BOOLEAN KiTestAlert(PKTHREAD Thread, PLIST_ENTRY current_entry; PKAPC Apc; PULONG Esp = (PULONG)UserContext->Esp; - KIRQL oldlvl; DPRINT("KiTestAlert(Thread %x, UserContext %x)\n"); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); + current_entry = Thread->ApcState.ApcListHead[1].Flink; if (current_entry == &Thread->ApcState.ApcListHead[1]) { - KeReleaseSpinLock( &PiApcLock, oldlvl ); return(FALSE); } @@ -84,26 +81,19 @@ BOOLEAN KiTestAlert(PKTHREAD Thread, return(TRUE); } -VOID KeApcProlog2() +VOID KeApcProlog2(PKAPC Apc) { - PETHREAD Thread = PsGetCurrentThread(); - PLIST_ENTRY current; - PKAPC Apc; - KIRQL oldlvl; - - KeLowerIrql( APC_LEVEL ); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); - while( !IsListEmpty( current ) ) - { - current = RemoveTailList( &(Thread->Tcb.ApcState.ApcListHead[0]) ); - KeReleaseSpinLock( &PiApcLock, oldlvl ); - Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry); - KeApcProlog3(Apc); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); - } - KeReleaseSpinLock( &PiApcLock, oldlvl ); - Thread->Tcb.WaitStatus = STATUS_ALERTED; - KeLowerIrql( PASSIVE_LEVEL ); + PKTHREAD Thread; + + DPRINT("KeApcProlog2(Apc %x)\n", Apc); + + Thread = Apc->Thread; + KeLowerIrql(PASSIVE_LEVEL); + KeApcProlog3(Apc); + PsSuspendThread(CONTAINING_RECORD(Thread,ETHREAD,Tcb), + NULL, + Thread->Alertable, + Thread->WaitMode); } VOID KeApcProlog3(PKAPC Apc) @@ -111,43 +101,72 @@ VOID KeApcProlog3(PKAPC Apc) * FUNCTION: This is called from the prolog proper (in assembly) to deliver * a kernel APC */ -{ - PKTHREAD Thread = KeGetCurrentThread(); - DPRINT("KeApcProlog2(Apc %x)\n",Apc); - InterlockedIncrement( &(Thread->ApcState.KernelApcInProgress) ); - InterlockedDecrement( &(Thread->ApcState.KernelApcPending) ); +{ + PKTHREAD Thread; + DPRINT("KeApcProlog2(Apc %x)\n",Apc); + KeEnterCriticalRegion(); + Apc->Thread->ApcState.KernelApcInProgress++; + Apc->Thread->ApcState.KernelApcPending--; + RemoveEntryList(&Apc->ApcListEntry); + Thread = Apc->Thread; Apc->KernelRoutine(Apc, &Apc->NormalRoutine, &Apc->NormalContext, &Apc->SystemArgument1, &Apc->SystemArgument2); - InterlockedDecrement( &(Thread->ApcState.KernelApcInProgress) ); + Thread->ApcState.KernelApcInProgress--; + KeLeaveCriticalRegion(); } -VOID KeDeliverKernelApc( PKTHREAD TargetThread ) +VOID KeDeliverKernelApc(PKAPC Apc) /* * FUNCTION: Simulates an interrupt on the target thread which will transfer * control to a kernel mode routine - * Must be called while holding the PiApcLock */ { + PKTHREAD TargetThread; PULONG Stack; DPRINT("KeDeliverKernelApc(Apc %x)\n", Apc); + + TargetThread = Apc->Thread; + if (TargetThread == KeGetCurrentThread()) { - KeApcProlog2(); + KeApcProlog3(Apc); return; } - TargetThread->Context.esp = TargetThread->Context.esp - 12; + if (TargetThread->Context.cs == KERNEL_CS) + { + TargetThread->Context.esp = TargetThread->Context.esp - 16; Stack = (PULONG)TargetThread->Context.esp; - Stack[0] = TargetThread->Context.eip; - Stack[1] = TargetThread->Context.cs; - Stack[2] = TargetThread->Context.eflags; + Stack[0] = TargetThread->Context.eax; + Stack[1] = TargetThread->Context.eip; + Stack[2] = TargetThread->Context.cs; + Stack[3] = TargetThread->Context.eflags; TargetThread->Context.eip = (ULONG)KeApcProlog; - + TargetThread->Context.eax = (ULONG)Apc; + } + else + { + TargetThread->Context.esp = TargetThread->Context.esp - 40; + Stack = (PULONG)TargetThread->Context.esp; + Stack[9] = TargetThread->Context.gs; + Stack[8] = TargetThread->Context.fs; + Stack[7] = TargetThread->Context.ds; + Stack[6] = TargetThread->Context.es; + Stack[5] = TargetThread->Context.ss; + Stack[4] = TargetThread->Context.esp; + Stack[3] = TargetThread->Context.eflags; + Stack[2] = TargetThread->Context.cs; + Stack[1] = TargetThread->Context.eip; + Stack[0] = TargetThread->Context.eax; + TargetThread->Context.eip = (ULONG)KeApcProlog; + TargetThread->Context.eax = (ULONG)Apc; + } + PsResumeThread(CONTAINING_RECORD(TargetThread,ETHREAD,Tcb), NULL); } @@ -171,7 +190,7 @@ VOID KeInsertQueueApc(PKAPC Apc, "SystemArgument2 %x, Mode %d)\n",Apc,SystemArgument1, SystemArgument2,Mode); - KeAcquireSpinLock( &PiApcLock, &oldlvl ); + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); Apc->SystemArgument1 = SystemArgument1; Apc->SystemArgument2 = SystemArgument2; @@ -201,16 +220,10 @@ VOID KeInsertQueueApc(PKAPC Apc, DPRINT("TargetThread->KernelApcDisable %d\n", TargetThread->KernelApcDisable); DPRINT("Apc->KernelRoutine %x\n", Apc->KernelRoutine); - if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 ) - if( TargetThread != PsGetCurrentThread() ) - { - PsSuspendThread( CONTAINING_RECORD( TargetThread, ETHREAD, Tcb ), NULL, TRUE, KernelMode ); - KeReleaseSpinLock( &PiApcLock, oldlvl ); - if( TargetThread->Alertable && TargetThread->WaitIrql < APC_LEVEL ) - KeDeliverKernelApc( TargetThread ); + if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1) + { + KeDeliverKernelApc(Apc); } - else if( TargetThread->Alertable && TargetThread->WaitIrql < APC_LEVEL ) - KeDeliverKernelApc( TargetThread ); else { DPRINT("Queuing APC for later delivery\n"); @@ -226,6 +239,7 @@ VOID KeInsertQueueApc(PKAPC Apc, PsResumeThread((PETHREAD)TargetThread, &Status); } + KeLowerIrql(oldlvl); } VOID KeInitializeApc(PKAPC Apc, @@ -326,9 +340,3 @@ NTSTATUS STDCALL NtTestAlert(VOID) KiTestAlert(KeGetCurrentThread(),NULL); return(STATUS_SUCCESS); } - -VOID PiInitApcManagement() -{ - KeInitializeSpinLock( &PiApcLock ); -} - diff --git a/reactos/ntoskrnl/ke/apchelp.c b/reactos/ntoskrnl/ke/apchelp.c index 49afda2e128..8787a828b61 100644 --- a/reactos/ntoskrnl/ke/apchelp.c +++ b/reactos/ntoskrnl/ke/apchelp.c @@ -3,7 +3,10 @@ void KeApcProlog(void); __asm__("\n\t.global _KeApcProlog\n\t" "_KeApcProlog:\n\t" "pusha\n\t" + "pushl %eax\n\t" "call _KeApcProlog2\n\t" + "popl %eax\n\t" "popa\n\t" + "popl %eax\n\t" "iret\n\t"); diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 50219403a1c..1086b1fb34e 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -140,7 +140,8 @@ static void print_address(PVOID address) current_entry = ModuleListHead.Flink; - while (current_entry != &ModuleListHead) + while (current_entry != &ModuleListHead && + current_entry != NULL) { current = CONTAINING_RECORD(current_entry, MODULE_OBJECT, ListEntry); @@ -327,6 +328,7 @@ asmlinkage void exception_handler(unsigned int edi, DbgPrint("\n"); DbgPrint("Killing current task\n"); + for(;;); KeLowerIrql(PASSIVE_LEVEL); if ((cs&0xffff) == USER_CS) { diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 142acad4406..a842042a533 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -262,6 +262,11 @@ asmlinkage int page_fault_handler(unsigned int cs, return(0); // KeBugCheck(0); } + if (PsGetCurrentProcess() == NULL) + { + DbgPrint("No current process\n"); + return(0); + } /* * Find the memory area for the faulting address diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 2f750a7794a..440c21a2aac 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -131,7 +131,7 @@ PVOID ObCreateObject(PHANDLE Handle, POBJECT_HEADER Header; NTSTATUS Status; - assert_irql(PASSIVE_LEVEL); + assert_irql(APC_LEVEL); DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n"); if (ObjectAttributes != NULL && diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index e9fe4d4b867..88fae138df7 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -27,5 +27,5 @@ VOID PiInitProcessManager(VOID) PsInitProcessManagment(); PsInitThreadManagment(); PsInitIdleThread(); - PiInitApcManagement(); +// PiInitApcManagement(); } diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 57d41fee756..cbc59bc4ceb 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.37 1999/12/12 00:49:00 phreak Exp $ +/* $Id: thread.c,v 1.38 1999/12/12 00:59:39 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -46,7 +46,7 @@ KSPIN_LOCK PiThreadListLock; /* * PURPOSE: List of threads associated with each priority level */ -static LIST_ENTRY PiThreadListHead = { &PiThreadListHead, &PiThreadListHead }; +static LIST_ENTRY PiThreadListHead; static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]; static BOOLEAN DoneInitYet = FALSE; ULONG PiNrThreads = 0; @@ -122,6 +122,11 @@ VOID PsDumpThreads(VOID) PLIST_ENTRY current_entry; PETHREAD current; + if (!DoneInitYet) + { + return; + } + current_entry = PiThreadListHead.Flink; while (current_entry != &PiThreadListHead) @@ -148,6 +153,8 @@ VOID PsReapThreads(VOID) // DPRINT1("PsReapThreads()\n"); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + current_entry = PiThreadListHead.Flink; while (current_entry != &PiThreadListHead) @@ -164,6 +171,8 @@ VOID PsReapThreads(VOID) ObDereferenceObject(current); } } + + KeReleaseSpinLock(&PiThreadListLock, oldIrql); } static PETHREAD PsScanThreadList (KPRIORITY Priority) @@ -213,6 +222,7 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) Candidate = PsScanThreadList(CurrentPriority); if (Candidate == CurrentThread) { + KeReleaseSpinLockFromDpcLevel(&PiThreadListLock); return; } if (Candidate != NULL) @@ -223,12 +233,9 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) CurrentThread = Candidate; - KeReleaseSpinLockFromDpcLevel( &PiThreadListLock ); - HalTaskSwitch(&CurrentThread->Tcb); - KeAcquireSpinLockAtDpcLevel( &PiThreadListLock ); - DPRINT( "Woken up, grabbed lock\n" ); + KeReleaseSpinLockFromDpcLevel(&PiThreadListLock); + HalTaskSwitch(&CurrentThread->Tcb); PsReapThreads(); - DPRINT( "Reaped\n" ); return; } } @@ -251,16 +258,23 @@ VOID PsDispatchThread(ULONG NewThreadStatus) KeAcquireSpinLock(&PiThreadListLock, &oldIrql); CurrentThread->Tcb.WaitIrql = oldIrql; // save wait Irql PsDispatchThreadNoLock(NewThreadStatus); - KeReleaseSpinLock(&PiThreadListLock, oldIrql); +// KeReleaseSpinLock(&PiThreadListLock, oldIrql); KeLowerIrql(oldIrql); // DPRINT("oldIrql %d\n",oldIrql); } -static VOID PiTimeoutThread( struct _KDPC *dpc, PVOID Context, PVOID arg1, PVOID arg2 ) +static VOID PiTimeoutThread(struct _KDPC *dpc, + PVOID Context, + PVOID arg1, + PVOID arg2 ) { - // wake up the thread, and tell it it timed out - NTSTATUS Status = STATUS_TIMEOUT; - PsResumeThread( (ETHREAD *)Context, &Status ); + /* + * wake up the thread, and tell it it timed out + */ + NTSTATUS Status = STATUS_TIMEOUT; + + DPRINT("PiTimeoutThread()\n"); + PsResumeThread((ETHREAD *)Context, &Status); } NTSTATUS PsInitializeThread(HANDLE ProcessHandle, @@ -381,6 +395,7 @@ ULONG PsSuspendThread(PETHREAD Thread, DPRINT("r %d Thread->Tcb.SuspendCount %d\n",r,Thread->Tcb.SuspendCount); if (r > 0) + { if (Thread != PsGetCurrentThread()) { if (Thread->Tcb.State == THREAD_STATE_RUNNABLE) @@ -391,6 +406,7 @@ ULONG PsSuspendThread(PETHREAD Thread, Thread->Tcb.Alertable = Alertable; Thread->Tcb.WaitMode = WaitMode; PiNrRunnableThreads--; + KeReleaseSpinLock(&PiThreadListLock, oldIrql); } else { @@ -400,15 +416,20 @@ ULONG PsSuspendThread(PETHREAD Thread, PiNrRunnableThreads--; Thread->Tcb.WaitIrql = oldIrql; // save wait IRQL PsDispatchThreadNoLock(THREAD_STATE_SUSPENDED); + KeLowerIrql(oldIrql); if (WaitStatus != NULL) { *WaitStatus = PsGetCurrentThread()->Tcb.WaitStatus; } } + } + else + { DPRINT("About to release ThreadListLock = %x\n", &PiThreadListLock); KeReleaseSpinLock(&PiThreadListLock, oldIrql); - DPRINT("PsSuspendThread() finished\n"); - return(r); + } + DPRINT("PsSuspendThread() finished\n"); + return(r); }