mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Don't use more than a single page for a TEB
svn path=/trunk/; revision=11143
This commit is contained in:
parent
f6fb22a9ef
commit
228cddee4a
6 changed files with 123 additions and 53 deletions
|
@ -359,6 +359,10 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown);
|
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown);
|
||||||
|
|
||||||
|
void MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
|
||||||
|
PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress);
|
||||||
|
|
||||||
/* npool.c *******************************************************************/
|
/* npool.c *******************************************************************/
|
||||||
|
|
||||||
VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
||||||
|
|
|
@ -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.69 2004/09/28 15:02:29 weiden Exp $
|
/* $Id: ps.h,v 1.70 2004/10/01 20:26:04 gvg Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Process manager definitions
|
* PURPOSE: Process manager definitions
|
||||||
|
@ -428,6 +428,10 @@ struct _EPROCESS
|
||||||
|
|
||||||
struct _EJOB* Job;
|
struct _EJOB* Job;
|
||||||
UINT JobStatus;
|
UINT JobStatus;
|
||||||
|
|
||||||
|
FAST_MUTEX TebLock;
|
||||||
|
PVOID TebBlock;
|
||||||
|
PVOID TebLastAllocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PROCESS_STATE_TERMINATED (1)
|
#define PROCESS_STATE_TERMINATED (1)
|
||||||
|
|
|
@ -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: anonmem.c,v 1.32 2004/09/28 19:49:20 gvg Exp $
|
/* $Id: anonmem.c,v 1.33 2004/10/01 20:26:04 gvg Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/anonmem.c
|
* FILE: ntoskrnl/mm/anonmem.c
|
||||||
|
@ -752,7 +752,7 @@ MmFreeVirtualMemory(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
|
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
|
|
@ -201,9 +201,6 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
InsertTailList(ListHead,inserted_entry);
|
InsertTailList(ListHead,inserted_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ROUND_DOWN_POW2(Addr, Boundary) ((ULONG_PTR) (Addr) & ~ ((Boundary) - 1))
|
|
||||||
#define ROUND_UP_POW2(Addr, Boundary) ROUND_DOWN_POW2((ULONG_PTR) (Addr) + (Boundary) - 1, Boundary)
|
|
||||||
|
|
||||||
static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity)
|
static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ListHead;
|
PLIST_ENTRY ListHead;
|
||||||
|
@ -230,7 +227,7 @@ static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
|
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
|
||||||
#endif
|
#endif
|
||||||
Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
|
Address = (PVOID) MM_ROUND_UP(Address, Granularity);
|
||||||
if (Address < next->BaseAddress)
|
if (Address < next->BaseAddress)
|
||||||
{
|
{
|
||||||
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
|
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
|
||||||
|
@ -244,7 +241,7 @@ static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
|
|
||||||
if (current_entry == ListHead)
|
if (current_entry == ListHead)
|
||||||
{
|
{
|
||||||
Address = (PVOID) ROUND_UP_POW2(AddressSpace->LowestAddress, Granularity);
|
Address = (PVOID) MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -253,7 +250,7 @@ static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
|
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
|
||||||
#endif
|
#endif
|
||||||
Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
|
Address = (PVOID) MM_ROUND_UP(Address, Granularity);
|
||||||
}
|
}
|
||||||
/* Check if enough space for the block */
|
/* Check if enough space for the block */
|
||||||
if (AddressSpace->LowestAddress < KERNEL_BASE)
|
if (AddressSpace->LowestAddress < KERNEL_BASE)
|
||||||
|
@ -313,7 +310,7 @@ static PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
BottomAddress = (PVOID) ((char *) BottomAddress + PAGE_SIZE); /* For a guard page preceding the area */
|
BottomAddress = (PVOID) ((char *) BottomAddress + PAGE_SIZE); /* For a guard page preceding the area */
|
||||||
#endif
|
#endif
|
||||||
BottomAddress = (PVOID) ROUND_UP_POW2(BottomAddress, Granularity);
|
BottomAddress = (PVOID) MM_ROUND_UP(BottomAddress, Granularity);
|
||||||
DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length));
|
DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length));
|
||||||
|
|
||||||
if (BottomAddress < TopAddress && BottomAddress < HighestAddress)
|
if (BottomAddress < TopAddress && BottomAddress < HighestAddress)
|
||||||
|
@ -323,7 +320,7 @@ static PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
if (Gap >= Length)
|
if (Gap >= Length)
|
||||||
{
|
{
|
||||||
DPRINT("Found gap at %p\n", (char*) TopAddress - Length);
|
DPRINT("Found gap at %p\n", (char*) TopAddress - Length);
|
||||||
return (PVOID) ROUND_DOWN_POW2((char*) TopAddress - Length + 1, Granularity);
|
return (PVOID) MM_ROUND_DOWN((char*) TopAddress - Length + 1, Granularity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TopAddress = (char*)current->BaseAddress - 1;
|
TopAddress = (char*)current->BaseAddress - 1;
|
||||||
|
@ -332,11 +329,11 @@ static PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
|
||||||
|
|
||||||
if (current_entry == ListHead)
|
if (current_entry == ListHead)
|
||||||
{
|
{
|
||||||
Address = (PVOID) ROUND_DOWN_POW2((char*) HighestAddress - Length + 1, Granularity);
|
Address = (PVOID) MM_ROUND_DOWN((char*) HighestAddress - Length + 1, Granularity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Address = (PVOID) ROUND_DOWN_POW2((char*)TopAddress - Length + 1, Granularity);
|
Address = (PVOID) MM_ROUND_DOWN((char*)TopAddress - Length + 1, Granularity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if enough space for the block */
|
/* Check if enough space for the block */
|
||||||
|
@ -596,8 +593,9 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmpLength = Length + ((ULONG_PTR) *BaseAddress - ROUND_DOWN_POW2(*BaseAddress, Granularity));
|
tmpLength = Length + ((ULONG_PTR) *BaseAddress
|
||||||
(*BaseAddress) = (PVOID) ROUND_DOWN_POW2(*BaseAddress, Granularity);
|
- (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity));
|
||||||
|
*BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity);
|
||||||
|
|
||||||
if (AddressSpace->LowestAddress == KERNEL_BASE &&
|
if (AddressSpace->LowestAddress == KERNEL_BASE &&
|
||||||
(*BaseAddress) < (PVOID)KERNEL_BASE)
|
(*BaseAddress) < (PVOID)KERNEL_BASE)
|
||||||
|
@ -643,3 +641,36 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
|
||||||
DPRINT("MmCreateMemoryArea() succeeded\n");
|
DPRINT("MmCreateMemoryArea() succeeded\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
|
||||||
|
PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress)
|
||||||
|
{
|
||||||
|
PMEMORY_AREA MemoryArea;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PMM_REGION Region;
|
||||||
|
BOOLEAN Reserved;
|
||||||
|
|
||||||
|
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress);
|
||||||
|
if (NULL != MemoryArea)
|
||||||
|
{
|
||||||
|
Entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink;
|
||||||
|
Reserved = TRUE;
|
||||||
|
while (Reserved && Entry != &MemoryArea->Data.VirtualMemoryData.RegionListHead)
|
||||||
|
{
|
||||||
|
Region = CONTAINING_RECORD(Entry, MM_REGION, RegionListEntry);
|
||||||
|
Reserved = (MEM_RESERVE == Region->Type);
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Reserved)
|
||||||
|
{
|
||||||
|
DPRINT("Release TebBlock at %p\n", TebBlock);
|
||||||
|
MmFreeVirtualMemory(Process, MemoryArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: create.c,v 1.81 2004/09/28 15:02:29 weiden Exp $
|
/* $Id: create.c,v 1.82 2004/10/01 20:26:05 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -504,51 +504,76 @@ PsCreateTeb(HANDLE ProcessHandle,
|
||||||
PETHREAD Thread,
|
PETHREAD Thread,
|
||||||
PUSER_STACK UserStack)
|
PUSER_STACK UserStack)
|
||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION Info;
|
PEPROCESS Process;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG ByteCount;
|
ULONG ByteCount;
|
||||||
ULONG RegionSize;
|
ULONG RegionSize;
|
||||||
ULONG TebSize;
|
ULONG TebSize;
|
||||||
PVOID TebBase;
|
PVOID TebBase;
|
||||||
TEB Teb;
|
TEB Teb;
|
||||||
ULONG ResultLength;
|
|
||||||
|
|
||||||
TebBase = (PVOID)0x7FFDE000;
|
|
||||||
TebSize = PAGE_SIZE;
|
TebSize = PAGE_SIZE;
|
||||||
|
|
||||||
while (TRUE)
|
if (NULL == Thread->ThreadsProcess)
|
||||||
{
|
{
|
||||||
Status = ZwQueryVirtualMemory(ProcessHandle,
|
/* We'll be allocating a 64k block here and only use 4k of it, but this
|
||||||
TebBase,
|
path should almost never be taken. Actually, I never saw it was taken,
|
||||||
MemoryBasicInformation,
|
so maybe we should just assert(NULL != Thread->ThreadsProcess) and
|
||||||
&Info,
|
move on */
|
||||||
sizeof(Info),
|
TebBase = NULL;
|
||||||
&ResultLength);
|
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
&TebBase,
|
||||||
{
|
0,
|
||||||
CPRINT("ZwQueryVirtualMemory (Status %x)\n", Status);
|
&TebSize,
|
||||||
KEBUGCHECK(0);
|
MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
|
||||||
}
|
PAGE_READWRITE);
|
||||||
/* FIXME: Race between this and the above check */
|
if (! NT_SUCCESS(Status))
|
||||||
if (Info.State == MEM_FREE)
|
{
|
||||||
{
|
DPRINT1("Failed to allocate virtual memory for TEB\n");
|
||||||
/* The TEB must reside in user space */
|
return Status;
|
||||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
}
|
||||||
&TebBase,
|
}
|
||||||
0,
|
else
|
||||||
&TebSize,
|
{
|
||||||
MEM_RESERVE | MEM_COMMIT,
|
Process = Thread->ThreadsProcess;
|
||||||
PAGE_READWRITE);
|
ExAcquireFastMutex(&Process->TebLock);
|
||||||
if (NT_SUCCESS(Status))
|
if (NULL == Process->TebBlock ||
|
||||||
{
|
Process->TebBlock == Process->TebLastAllocated)
|
||||||
break;
|
{
|
||||||
}
|
Process->TebBlock = NULL;
|
||||||
}
|
RegionSize = MM_VIRTMEM_GRANULARITY;
|
||||||
|
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||||
TebBase = (char*)TebBase - TebSize;
|
&Process->TebBlock,
|
||||||
|
0,
|
||||||
|
&RegionSize,
|
||||||
|
MEM_RESERVE | MEM_TOP_DOWN,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (! NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExReleaseFastMutex(&Process->TebLock);
|
||||||
|
DPRINT1("Failed to reserve virtual memory for TEB\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
Process->TebLastAllocated = (PVOID) ((char *) Process->TebBlock + RegionSize);
|
||||||
|
}
|
||||||
|
TebBase = (PVOID) ((char *) Process->TebLastAllocated - PAGE_SIZE);
|
||||||
|
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&TebBase,
|
||||||
|
0,
|
||||||
|
&TebSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (! NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to commit virtual memory for TEB\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
Process->TebLastAllocated = TebBase;
|
||||||
|
ExReleaseFastMutex(&Process->TebLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
|
DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
|
||||||
|
assert(NULL != TebBase && PAGE_SIZE <= TebSize);
|
||||||
|
|
||||||
RtlZeroMemory(&Teb, sizeof(TEB));
|
RtlZeroMemory(&Teb, sizeof(TEB));
|
||||||
/* set all pointers to and from the TEB */
|
/* set all pointers to and from the TEB */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: process.c,v 1.143 2004/09/28 19:49:21 gvg Exp $
|
/* $Id: process.c,v 1.144 2004/10/01 20:26:05 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -417,6 +417,7 @@ PsCreatePeb(HANDLE ProcessHandle,
|
||||||
PEPROCESS Process,
|
PEPROCESS Process,
|
||||||
PVOID ImageBase)
|
PVOID ImageBase)
|
||||||
{
|
{
|
||||||
|
ULONG AllocSize;
|
||||||
ULONG PebSize;
|
ULONG PebSize;
|
||||||
PPEB Peb;
|
PPEB Peb;
|
||||||
LARGE_INTEGER SectionOffset;
|
LARGE_INTEGER SectionOffset;
|
||||||
|
@ -425,12 +426,12 @@ PsCreatePeb(HANDLE ProcessHandle,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Allocate the Process Environment Block (PEB) */
|
/* Allocate the Process Environment Block (PEB) */
|
||||||
Peb = (PPEB)PEB_BASE;
|
Process->TebBlock = (PVOID) MM_ROUND_DOWN(PEB_BASE, MM_VIRTMEM_GRANULARITY);
|
||||||
PebSize = PAGE_SIZE;
|
AllocSize = MM_VIRTMEM_GRANULARITY;
|
||||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
(PVOID*)&Peb,
|
&Process->TebBlock,
|
||||||
0,
|
0,
|
||||||
&PebSize,
|
&AllocSize,
|
||||||
MEM_RESERVE,
|
MEM_RESERVE,
|
||||||
PAGE_READWRITE);
|
PAGE_READWRITE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -438,6 +439,8 @@ PsCreatePeb(HANDLE ProcessHandle,
|
||||||
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
assert((ULONG_PTR) Process->TebBlock <= PEB_BASE &&
|
||||||
|
PEB_BASE + PAGE_SIZE <= (ULONG_PTR) Process->TebBlock + AllocSize);
|
||||||
Peb = (PPEB)PEB_BASE;
|
Peb = (PPEB)PEB_BASE;
|
||||||
PebSize = PAGE_SIZE;
|
PebSize = PAGE_SIZE;
|
||||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
@ -452,6 +455,8 @@ PsCreatePeb(HANDLE ProcessHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
|
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
|
||||||
|
assert((PPEB) PEB_BASE == Peb && PAGE_SIZE <= PebSize);
|
||||||
|
Process->TebLastAllocated = (PVOID) Peb;
|
||||||
|
|
||||||
ViewSize = 0;
|
ViewSize = 0;
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
@ -730,6 +735,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
|
||||||
InitializeListHead(&Process->ThreadListHead);
|
InitializeListHead(&Process->ThreadListHead);
|
||||||
KeReleaseSpinLock(&PsProcessListLock, oldIrql);
|
KeReleaseSpinLock(&PsProcessListLock, oldIrql);
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&Process->TebLock);
|
||||||
Process->Pcb.State = PROCESS_STATE_ACTIVE;
|
Process->Pcb.State = PROCESS_STATE_ACTIVE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue