mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:56:00 +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,
|
VOID STDCALL KeInitializeApc (IN PKAPC Apc,
|
||||||
IN PKTHREAD Thread,
|
IN PKTHREAD Thread,
|
||||||
IN UCHAR StateIndex,
|
IN KAPC_ENVIRONMENT TargetEnvironment,
|
||||||
IN PKKERNEL_ROUTINE KernelRoutine,
|
IN PKKERNEL_ROUTINE KernelRoutine,
|
||||||
IN PKRUNDOWN_ROUTINE RundownRoutine,
|
IN PKRUNDOWN_ROUTINE RundownRoutine,
|
||||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||||
IN UCHAR Mode,
|
IN KPROCESSOR_MODE Mode,
|
||||||
IN PVOID Context);
|
IN PVOID Context);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,12 @@ VOID KeInit1(VOID);
|
||||||
VOID KeInit2(VOID);
|
VOID KeInit2(VOID);
|
||||||
|
|
||||||
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
|
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
KiSwapApcEnvironment(
|
||||||
|
struct _KTHREAD* Thread,
|
||||||
|
struct _KPROCESS* NewProcess);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Pc);
|
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Pc);
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Process manager definitions
|
* PURPOSE: Process manager definitions
|
||||||
|
@ -125,7 +125,7 @@ typedef struct _KTHREAD
|
||||||
PVOID CallbackStack; /* 120 */
|
PVOID CallbackStack; /* 120 */
|
||||||
BOOL Win32Thread; /* 124 */
|
BOOL Win32Thread; /* 124 */
|
||||||
struct _KTRAP_FRAME* TrapFrame; /* 128 */
|
struct _KTRAP_FRAME* TrapFrame; /* 128 */
|
||||||
PVOID ApcStatePointer[2]; /* 12C */
|
PKAPC_STATE ApcStatePointer[2]; /* 12C */
|
||||||
UCHAR EnableStackSwap; /* 134 */
|
UCHAR EnableStackSwap; /* 134 */
|
||||||
UCHAR LargeStack; /* 135 */
|
UCHAR LargeStack; /* 135 */
|
||||||
UCHAR ResourceIndex; /* 136 */
|
UCHAR ResourceIndex; /* 136 */
|
||||||
|
|
|
@ -461,11 +461,11 @@ VOID STDCALL
|
||||||
KeInitializeApc(
|
KeInitializeApc(
|
||||||
IN PKAPC Apc,
|
IN PKAPC Apc,
|
||||||
IN PKTHREAD Thread,
|
IN PKTHREAD Thread,
|
||||||
IN UCHAR StateIndex,
|
IN KAPC_ENVIRONMENT TargetEnvironment,
|
||||||
IN PKKERNEL_ROUTINE KernelRoutine,
|
IN PKKERNEL_ROUTINE KernelRoutine,
|
||||||
IN PKRUNDOWN_ROUTINE RundownRoutine,
|
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
|
||||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||||
IN UCHAR Mode,
|
IN KPROCESSOR_MODE Mode,
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Initialize an APC object
|
* FUNCTION: Initialize an APC object
|
||||||
|
@ -481,11 +481,9 @@ KeInitializeApc(
|
||||||
* Context = Parameter to be passed to the APC routine
|
* Context = Parameter to be passed to the APC routine
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
KAPC_ENVIRONMENT Environment = (KAPC_ENVIRONMENT) StateIndex;
|
|
||||||
|
|
||||||
DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
|
DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
|
||||||
"KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %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);
|
NormalRoutine,Mode,Context);
|
||||||
|
|
||||||
memset(Apc, 0, sizeof(KAPC));
|
memset(Apc, 0, sizeof(KAPC));
|
||||||
|
@ -498,18 +496,18 @@ KeInitializeApc(
|
||||||
Apc->NormalContext = Context;
|
Apc->NormalContext = Context;
|
||||||
Apc->Inserted = FALSE;
|
Apc->Inserted = FALSE;
|
||||||
|
|
||||||
if (Environment == CurrentApcEnvironment)
|
if (TargetEnvironment == CurrentApcEnvironment)
|
||||||
{
|
{
|
||||||
Apc->ApcStateIndex = Thread->ApcStateIndex;
|
Apc->ApcStateIndex = Thread->ApcStateIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Apc->ApcStateIndex = Environment;
|
Apc->ApcStateIndex = TargetEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Apc->NormalRoutine != NULL)
|
if (Apc->NormalRoutine != NULL)
|
||||||
{
|
{
|
||||||
Apc->ApcMode = (KPROCESSOR_MODE) Mode;
|
Apc->ApcMode = Mode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -592,3 +590,76 @@ PiInitApcManagement(VOID)
|
||||||
KeInitializeSpinLock(&PiApcLock);
|
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
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Microkernel thread support
|
* PURPOSE: Microkernel thread support
|
||||||
|
@ -180,10 +180,21 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
Thread->Quantum = 0;
|
Thread->Quantum = 0;
|
||||||
memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
|
memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
|
||||||
Thread->LegoData = 0;
|
Thread->LegoData = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Why this?
|
* 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->UserAffinity = Process->Affinity;
|
||||||
Thread->SystemAffinityActive = 0;
|
Thread->SystemAffinityActive = 0;
|
||||||
Thread->PowerState = 0;
|
Thread->PowerState = 0;
|
||||||
|
@ -202,8 +213,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
Thread->CallbackStack = NULL;
|
Thread->CallbackStack = NULL;
|
||||||
Thread->Win32Thread = 0;
|
Thread->Win32Thread = 0;
|
||||||
Thread->TrapFrame = NULL;
|
Thread->TrapFrame = NULL;
|
||||||
Thread->ApcStatePointer[0] = NULL;
|
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
|
||||||
Thread->ApcStatePointer[1] = NULL;
|
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
|
||||||
Thread->EnableStackSwap = 0;
|
Thread->EnableStackSwap = 0;
|
||||||
Thread->LargeStack = 0;
|
Thread->LargeStack = 0;
|
||||||
Thread->ResourceIndex = 0;
|
Thread->ResourceIndex = 0;
|
||||||
|
@ -211,9 +222,15 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
Thread->KernelTime = 0;
|
Thread->KernelTime = 0;
|
||||||
Thread->UserTime = 0;
|
Thread->UserTime = 0;
|
||||||
memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
|
memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
|
||||||
|
|
||||||
|
/* FIXME: is this correct? */
|
||||||
Thread->Alertable = 1;
|
Thread->Alertable = 1;
|
||||||
Thread->ApcStateIndex = 0;
|
|
||||||
Thread->ApcQueueable = 0;
|
Thread->ApcStateIndex = OriginalApcEnvironment;
|
||||||
|
|
||||||
|
/* FIXME: not all thread are ApcQueueable! */
|
||||||
|
Thread->ApcQueueable = TRUE;
|
||||||
|
|
||||||
Thread->AutoAlignment = 0;
|
Thread->AutoAlignment = 0;
|
||||||
KeInitializeApc(&Thread->SuspendApc,
|
KeInitializeApc(&Thread->SuspendApc,
|
||||||
Thread,
|
Thread,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/process.c
|
* FILE: ntoskrnl/ke/process.c
|
||||||
|
@ -62,6 +62,8 @@ KeAttachProcess (PEPROCESS Process)
|
||||||
|
|
||||||
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
|
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
|
||||||
|
|
||||||
|
KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb);
|
||||||
|
|
||||||
/* The stack of the current process may be located in a page which is
|
/* 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.
|
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,
|
That would lead to a page fault when this function returns. However,
|
||||||
|
@ -83,7 +85,6 @@ KeAttachProcess (PEPROCESS Process)
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "r" (PageDir));
|
: "r" (PageDir));
|
||||||
|
|
||||||
|
|
||||||
KeLowerIrql(oldlvl);
|
KeLowerIrql(oldlvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +110,8 @@ KeDetachProcess (VOID)
|
||||||
|
|
||||||
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
|
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
|
||||||
|
|
||||||
|
KiSwapApcEnvironment(&CurrentThread->Tcb, &CurrentThread->OldProcess->Pcb);
|
||||||
|
|
||||||
CurrentThread->ThreadsProcess = CurrentThread->OldProcess;
|
CurrentThread->ThreadsProcess = CurrentThread->OldProcess;
|
||||||
CurrentThread->OldProcess = NULL;
|
CurrentThread->OldProcess = NULL;
|
||||||
PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart;
|
PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue