Backed out Philip Susi's changes for further testing

Returned kernel to working state.
Made exception handling more tolerant

svn path=/trunk/; revision=862
This commit is contained in:
David Welch 1999-12-12 00:59:39 +00:00
parent a590b25e46
commit f822a2a9d9
8 changed files with 132 additions and 92 deletions

View file

@ -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)

View file

@ -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 <internal/debug.h>
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 );
}

View file

@ -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");

View file

@ -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)
{

View file

@ -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

View file

@ -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 &&

View file

@ -27,5 +27,5 @@ VOID PiInitProcessManager(VOID)
PsInitProcessManagment();
PsInitThreadManagment();
PsInitIdleThread();
PiInitApcManagement();
// PiInitApcManagement();
}

View file

@ -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);
}