- Don't allocate/free a new callback on each callback to user mode.

svn path=/trunk/; revision=5230
This commit is contained in:
David Welch 2003-07-23 19:13:37 +00:00
parent b3503c4a97
commit 6e6bff4228
3 changed files with 55 additions and 5 deletions

View file

@ -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.50 2003/07/17 16:57:38 silverblade Exp $ /* $Id: ps.h,v 1.51 2003/07/23 19:13:37 dwelch Exp $
* *
* FILE: ntoskrnl/ke/kthread.c * FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions * PURPOSE: Process manager definitions
@ -540,6 +540,9 @@ PsTerminateWin32Process (PEPROCESS Process);
VOID VOID
PsTerminateWin32Thread (PETHREAD Thread); PsTerminateWin32Thread (PETHREAD Thread);
VOID
PsInitialiseW32Call(VOID);
#endif /* ASSEMBLER */ #endif /* ASSEMBLER */
#endif /* __INCLUDE_INTERNAL_PS_H */ #endif /* __INCLUDE_INTERNAL_PS_H */

View file

@ -1,4 +1,4 @@
/* $Id: psmgr.c,v 1.15 2003/07/11 01:23:15 royce Exp $ /* $Id: psmgr.c,v 1.16 2003/07/23 19:13:37 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,6 +33,7 @@ VOID PiInitProcessManager(VOID)
PsInitIdleThread(); PsInitIdleThread();
PiInitApcManagement(); PiInitApcManagement();
PsInitialiseSuspendImplementation(); PsInitialiseSuspendImplementation();
PsInitialiseW32Call();
} }

View file

@ -1,4 +1,4 @@
/* $Id: w32call.c,v 1.7 2003/07/21 21:53:53 royce Exp $ /* $Id: w32call.c,v 1.8 2003/07/23 19:13:37 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -46,8 +46,22 @@ typedef struct _NTW32CALL_SAVED_STATE
PVOID SavedCallbackStack; PVOID SavedCallbackStack;
} NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE; } NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
typedef struct
{
PVOID BaseAddress;
LIST_ENTRY ListEntry;
} NTW32CALL_CALLBACK_STACK, *PNTW32CALL_CALLBACK_STACK;
static LIST_ENTRY CallbackStackListHead;
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
VOID
PsInitialiseW32Call(VOID)
{
InitializeListHead(&CallbackStackListHead);
}
NTSTATUS STDCALL NTSTATUS STDCALL
NtCallbackReturn (PVOID Result, NtCallbackReturn (PVOID Result,
ULONG ResultLength, ULONG ResultLength,
@ -145,6 +159,22 @@ PsFreeCallbackStack(PVOID StackLimit)
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());
} }
VOID
PsFreeCallbackStacks(VOID)
{
PLIST_ENTRY CurrentListEntry;
PNTW32CALL_CALLBACK_STACK Current;
while (!IsListEmpty(&CallbackStackListHead))
{
CurrentListEntry = RemoveHeadList(&CallbackStackListHead);
Current = CONTAINING_RECORD(CurrentListEntry, NTW32CALL_CALLBACK_STACK,
ListEntry);
PsFreeCallbackStack(Current->BaseAddress);
ExFreePool(Current);
}
}
PVOID STATIC PVOID STATIC
PsAllocateCallbackStack(ULONG StackSize) PsAllocateCallbackStack(ULONG StackSize)
{ {
@ -202,6 +232,7 @@ NtW32Call (IN ULONG RoutineIndex,
KIRQL oldIrql; KIRQL oldIrql;
NTSTATUS CallbackStatus; NTSTATUS CallbackStatus;
NTW32CALL_SAVED_STATE SavedState; NTW32CALL_SAVED_STATE SavedState;
PNTW32CALL_CALLBACK_STACK AssignedStack;
DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n", DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
RoutineIndex, Argument, ArgumentLength); RoutineIndex, Argument, ArgumentLength);
@ -210,7 +241,22 @@ NtW32Call (IN ULONG RoutineIndex,
/* Set up the new kernel and user environment. */ /* Set up the new kernel and user environment. */
StackSize = (ULONG)(Thread->Tcb.StackBase - Thread->Tcb.StackLimit); StackSize = (ULONG)(Thread->Tcb.StackBase - Thread->Tcb.StackLimit);
NewStack = PsAllocateCallbackStack(StackSize); if (IsListEmpty(&CallbackStackListHead))
{
NewStack = PsAllocateCallbackStack(StackSize);
AssignedStack = ExAllocatePool(NonPagedPool,
sizeof(NTW32CALL_CALLBACK_STACK));
AssignedStack->BaseAddress = NewStack;
}
else
{
PLIST_ENTRY StackEntry;
StackEntry = RemoveHeadList(&CallbackStackListHead);
AssignedStack = CONTAINING_RECORD(StackEntry, NTW32CALL_CALLBACK_STACK,
ListEntry);
NewStack = AssignedStack->BaseAddress;
}
/* FIXME: Need to check whether we were interrupted from v86 mode. */ /* FIXME: Need to check whether we were interrupted from v86 mode. */
memcpy(NewStack + StackSize - sizeof(KTRAP_FRAME), Thread->Tcb.TrapFrame, memcpy(NewStack + StackSize - sizeof(KTRAP_FRAME), Thread->Tcb.TrapFrame,
sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD))); sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
@ -245,7 +291,7 @@ NtW32Call (IN ULONG RoutineIndex,
* modified. * modified.
*/ */
KeLowerIrql(PASSIVE_LEVEL); KeLowerIrql(PASSIVE_LEVEL);
PsFreeCallbackStack(NewStack); InsertTailList(&CallbackStackListHead, &AssignedStack->ListEntry);
return(CallbackStatus); return(CallbackStatus);
} }