svn path=/trunk/; revision=6807
This commit is contained in:
Gunnar Dalsnes 2003-11-27 01:13:05 +00:00
parent 05dd288048
commit b4d0d3aaf0
6 changed files with 118 additions and 21 deletions

View file

@ -103,11 +103,11 @@ struct _KTHREAD* STDCALL KeGetCurrentThread (VOID);
VOID STDCALL KeInitializeApc (IN PKAPC Apc,
IN PKTHREAD Thread,
IN UCHAR StateIndex,
IN KAPC_ENVIRONMENT TargetEnvironment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine,
IN PKNORMAL_ROUTINE NormalRoutine,
IN UCHAR Mode,
IN KPROCESSOR_MODE Mode,
IN PVOID Context);

View file

@ -88,6 +88,12 @@ VOID KeInit1(VOID);
VOID KeInit2(VOID);
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
VOID FASTCALL
KiSwapApcEnvironment(
struct _KTHREAD* Thread,
struct _KPROCESS* NewProcess);
VOID
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Pc);
VOID

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: ps.h,v 1.53 2003/10/15 17:04:39 navaraf Exp $
/* $Id: ps.h,v 1.54 2003/11/27 01:06:48 gdalsnes Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions
@ -125,7 +125,7 @@ typedef struct _KTHREAD
PVOID CallbackStack; /* 120 */
BOOL Win32Thread; /* 124 */
struct _KTRAP_FRAME* TrapFrame; /* 128 */
PVOID ApcStatePointer[2]; /* 12C */
PKAPC_STATE ApcStatePointer[2]; /* 12C */
UCHAR EnableStackSwap; /* 134 */
UCHAR LargeStack; /* 135 */
UCHAR ResourceIndex; /* 136 */

View file

@ -461,11 +461,11 @@ VOID STDCALL
KeInitializeApc(
IN PKAPC Apc,
IN PKTHREAD Thread,
IN UCHAR StateIndex,
IN KAPC_ENVIRONMENT TargetEnvironment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine,
IN UCHAR Mode,
IN KPROCESSOR_MODE Mode,
IN PVOID Context)
/*
* FUNCTION: Initialize an APC object
@ -481,11 +481,9 @@ KeInitializeApc(
* Context = Parameter to be passed to the APC routine
*/
{
KAPC_ENVIRONMENT Environment = (KAPC_ENVIRONMENT) StateIndex;
DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
"KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
"Context %x)\n",Apc,Thread,Environment,KernelRoutine,RundownRoutine,
"Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine,
NormalRoutine,Mode,Context);
memset(Apc, 0, sizeof(KAPC));
@ -498,18 +496,18 @@ KeInitializeApc(
Apc->NormalContext = Context;
Apc->Inserted = FALSE;
if (Environment == CurrentApcEnvironment)
if (TargetEnvironment == CurrentApcEnvironment)
{
Apc->ApcStateIndex = Thread->ApcStateIndex;
}
else
{
Apc->ApcStateIndex = Environment;
Apc->ApcStateIndex = TargetEnvironment;
}
if (Apc->NormalRoutine != NULL)
{
Apc->ApcMode = (KPROCESSOR_MODE) Mode;
Apc->ApcMode = Mode;
}
else
{
@ -592,3 +590,76 @@ PiInitApcManagement(VOID)
KeInitializeSpinLock(&PiApcLock);
}
VOID FASTCALL
KiSwapApcEnvironment(
PKTHREAD Thread,
PKPROCESS NewProcess)
{
/* FIXME: Grab the process apc lock or the PiApcLock? And why does both exist? */
if (Thread->ApcStateIndex == AttachedApcEnvironment)
{
/* NewProcess must be the same as in the original-environment */
assert(NewProcess == Thread->ApcStatePointer[OriginalApcEnvironment]->Process);
/*
FIXME: Deliver any pending apc's queued to the attached environment before
switching back to the original environment.
This is not crucial thou, since i don't think we'll ever target apc's
to attached environments (or?)...
Remove the following asserts if implementing this.
-Gunnar
*/
/* we don't support targeting apc's at attached-environments (yet)... */
assert(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]));
assert(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]));
assert(Thread->ApcState.KernelApcInProgress == FALSE);
assert(Thread->ApcState.KernelApcPending == FALSE);
assert(Thread->ApcState.UserApcPending == FALSE);
/* restore backup of original environment */
Thread->ApcState = Thread->SavedApcState;
/* update environment pointers */
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
/* update current-environment index */
Thread->ApcStateIndex = OriginalApcEnvironment;
}
else if (Thread->ApcStateIndex == OriginalApcEnvironment)
{
/* backup original environment */
Thread->SavedApcState = Thread->ApcState;
/*
FIXME: Is it possible to target an apc to an attached environment even if the
thread is not currently attached???? If so, then this is bougus since it
reinitializes the attached apc environment then located in SavedApcState.
-Gunnar
*/
/* setup a fresh new attached environment */
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
Thread->ApcState.Process = NewProcess;
Thread->ApcState.KernelApcInProgress = FALSE;
Thread->ApcState.KernelApcPending = FALSE;
Thread->ApcState.UserApcPending = FALSE;
/* update environment pointers */
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
/* update current-environment index */
Thread->ApcStateIndex = AttachedApcEnvironment;
}
else
{
KEBUGCHECK(0);
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: kthread.c,v 1.42 2003/07/21 21:53:51 royce Exp $
/* $Id: kthread.c,v 1.43 2003/11/27 01:02:23 gdalsnes Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
@ -180,10 +180,21 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->Quantum = 0;
memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
Thread->LegoData = 0;
/*
* FIXME: Why this?
*/
Thread->KernelApcDisable = 1;
// Thread->KernelApcDisable = 1;
/*
It may be correct to have regular kmode APC disabled
until the thread has been fully created, BUT the problem is: they are
currently never enabled again! So until somone figures out how
this really work, I'm setting regular kmode APC's intially enabled.
-Gunnar
*/
Thread->KernelApcDisable = 0;
Thread->UserAffinity = Process->Affinity;
Thread->SystemAffinityActive = 0;
Thread->PowerState = 0;
@ -202,8 +213,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->CallbackStack = NULL;
Thread->Win32Thread = 0;
Thread->TrapFrame = NULL;
Thread->ApcStatePointer[0] = NULL;
Thread->ApcStatePointer[1] = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->EnableStackSwap = 0;
Thread->LargeStack = 0;
Thread->ResourceIndex = 0;
@ -211,9 +222,15 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->KernelTime = 0;
Thread->UserTime = 0;
memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
/* FIXME: is this correct? */
Thread->Alertable = 1;
Thread->ApcStateIndex = 0;
Thread->ApcQueueable = 0;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* FIXME: not all thread are ApcQueueable! */
Thread->ApcQueueable = TRUE;
Thread->AutoAlignment = 0;
KeInitializeApc(&Thread->SuspendApc,
Thread,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: process.c,v 1.16 2003/07/21 21:53:51 royce Exp $
/* $Id: process.c,v 1.17 2003/11/27 01:09:10 gdalsnes Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c
@ -62,6 +62,8 @@ KeAttachProcess (PEPROCESS Process)
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb);
/* The stack of the current process may be located in a page which is
not present in the page directory of the process we're attaching to.
That would lead to a page fault when this function returns. However,
@ -83,7 +85,6 @@ KeAttachProcess (PEPROCESS Process)
: /* no outputs */
: "r" (PageDir));
KeLowerIrql(oldlvl);
}
@ -108,6 +109,8 @@ KeDetachProcess (VOID)
}
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KiSwapApcEnvironment(&CurrentThread->Tcb, &CurrentThread->OldProcess->Pcb);
CurrentThread->ThreadsProcess = CurrentThread->OldProcess;
CurrentThread->OldProcess = NULL;