mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 13:11:22 +00:00
apc work
svn path=/trunk/; revision=6807
This commit is contained in:
parent
05dd288048
commit
b4d0d3aaf0
6 changed files with 118 additions and 21 deletions
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue