6 modified files
reactos/ntoskrnl/include/internal
diff -u -r1.69 -r1.70
--- ps.h 28 Sep 2004 15:02:29 -0000 1.69
+++ ps.h 1 Oct 2004 20:26:04 -0000 1.70
@@ -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.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
* PURPOSE: Process manager definitions
@@ -428,6 +428,10 @@
struct _EJOB* Job;
UINT JobStatus;
+
+ FAST_MUTEX TebLock;
+ PVOID TebBlock;
+ PVOID TebLastAllocated;
};
#define PROCESS_STATE_TERMINATED (1)
reactos/ntoskrnl/include/internal
diff -u -r1.89 -r1.90
--- mm.h 28 Sep 2004 19:49:20 -0000 1.89
+++ mm.h 1 Oct 2004 20:26:04 -0000 1.90
@@ -359,6 +359,10 @@
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown);
+void MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
+ PMADDRESS_SPACE AddressSpace,
+ PVOID BaseAddress);
+
/* npool.c *******************************************************************/
VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
reactos/ntoskrnl/mm
diff -u -r1.32 -r1.33
--- anonmem.c 28 Sep 2004 19:49:20 -0000 1.32
+++ anonmem.c 1 Oct 2004 20:26:04 -0000 1.33
@@ -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: 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
* FILE: ntoskrnl/mm/anonmem.c
@@ -752,7 +752,7 @@
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS STDCALL
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
reactos/ntoskrnl/mm
diff -u -r1.67 -r1.68
--- marea.c 28 Sep 2004 19:49:21 -0000 1.67
+++ marea.c 1 Oct 2004 20:26:04 -0000 1.68
@@ -201,9 +201,6 @@
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)
{
PLIST_ENTRY ListHead;
@@ -230,7 +227,7 @@
#ifdef DBG
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
#endif
- Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
+ Address = (PVOID) MM_ROUND_UP(Address, Granularity);
if (Address < next->BaseAddress)
{
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
@@ -244,7 +241,7 @@
if (current_entry == ListHead)
{
- Address = (PVOID) ROUND_UP_POW2(AddressSpace->LowestAddress, Granularity);
+ Address = (PVOID) MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);
}
else
{
@@ -253,7 +250,7 @@
#ifdef DBG
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
#endif
- Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
+ Address = (PVOID) MM_ROUND_UP(Address, Granularity);
}
/* Check if enough space for the block */
if (AddressSpace->LowestAddress < KERNEL_BASE)
@@ -313,7 +310,7 @@
#ifdef DBG
BottomAddress = (PVOID) ((char *) BottomAddress + PAGE_SIZE); /* For a guard page preceding the area */
#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));
if (BottomAddress < TopAddress && BottomAddress < HighestAddress)
@@ -323,7 +320,7 @@
if (Gap >= 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;
@@ -332,11 +329,11 @@
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
{
- 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 */
@@ -596,8 +593,9 @@
}
else
{
- tmpLength = Length + ((ULONG_PTR) *BaseAddress - ROUND_DOWN_POW2(*BaseAddress, Granularity));
- (*BaseAddress) = (PVOID) ROUND_DOWN_POW2(*BaseAddress, Granularity);
+ tmpLength = Length + ((ULONG_PTR) *BaseAddress
+ - (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity));
+ *BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity);
if (AddressSpace->LowestAddress == KERNEL_BASE &&
(*BaseAddress) < (PVOID)KERNEL_BASE)
@@ -643,3 +641,36 @@
DPRINT("MmCreateMemoryArea() succeeded\n");
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 */
reactos/ntoskrnl/ps
diff -u -r1.81 -r1.82
--- create.c 28 Sep 2004 15:02:29 -0000 1.81
+++ create.c 1 Oct 2004 20:26:05 -0000 1.82
@@ -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
* PROJECT: ReactOS kernel
@@ -504,51 +504,76 @@
PETHREAD Thread,
PUSER_STACK UserStack)
{
- MEMORY_BASIC_INFORMATION Info;
+ PEPROCESS Process;
NTSTATUS Status;
ULONG ByteCount;
ULONG RegionSize;
ULONG TebSize;
PVOID TebBase;
TEB Teb;
- ULONG ResultLength;
- TebBase = (PVOID)0x7FFDE000;
TebSize = PAGE_SIZE;
- while (TRUE)
+ if (NULL == Thread->ThreadsProcess)
{
- Status = ZwQueryVirtualMemory(ProcessHandle,
- TebBase,
- MemoryBasicInformation,
- &Info,
- sizeof(Info),
- &ResultLength);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("ZwQueryVirtualMemory (Status %x)\n", Status);
- KEBUGCHECK(0);
- }
- /* FIXME: Race between this and the above check */
- if (Info.State == MEM_FREE)
- {
- /* The TEB must reside in user space */
- Status = ZwAllocateVirtualMemory(ProcessHandle,
- &TebBase,
- 0,
- &TebSize,
- MEM_RESERVE | MEM_COMMIT,
- PAGE_READWRITE);
- if (NT_SUCCESS(Status))
- {
- break;
- }
- }
-
- TebBase = (char*)TebBase - TebSize;
+ /* We'll be allocating a 64k block here and only use 4k of it, but this
+ path should almost never be taken. Actually, I never saw it was taken,
+ so maybe we should just assert(NULL != Thread->ThreadsProcess) and
+ move on */
+ TebBase = NULL;
+ Status = ZwAllocateVirtualMemory(ProcessHandle,
+ &TebBase,
+ 0,
+ &TebSize,
+ MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to allocate virtual memory for TEB\n");
+ return Status;
+ }
+ }
+ else
+ {
+ Process = Thread->ThreadsProcess;
+ ExAcquireFastMutex(&Process->TebLock);
+ if (NULL == Process->TebBlock ||
+ Process->TebBlock == Process->TebLastAllocated)
+ {
+ Process->TebBlock = NULL;
+ RegionSize = MM_VIRTMEM_GRANULARITY;
+ Status = ZwAllocateVirtualMemory(ProcessHandle,
+ &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);
+ assert(NULL != TebBase && PAGE_SIZE <= TebSize);
RtlZeroMemory(&Teb, sizeof(TEB));
/* set all pointers to and from the TEB */
reactos/ntoskrnl/ps
diff -u -r1.143 -r1.144
--- process.c 28 Sep 2004 19:49:21 -0000 1.143
+++ process.c 1 Oct 2004 20:26:05 -0000 1.144
@@ -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
* PROJECT: ReactOS kernel
@@ -417,6 +417,7 @@
PEPROCESS Process,
PVOID ImageBase)
{
+ ULONG AllocSize;
ULONG PebSize;
PPEB Peb;
LARGE_INTEGER SectionOffset;
@@ -425,12 +426,12 @@
NTSTATUS Status;
/* Allocate the Process Environment Block (PEB) */
- Peb = (PPEB)PEB_BASE;
- PebSize = PAGE_SIZE;
+ Process->TebBlock = (PVOID) MM_ROUND_DOWN(PEB_BASE, MM_VIRTMEM_GRANULARITY);
+ AllocSize = MM_VIRTMEM_GRANULARITY;
Status = NtAllocateVirtualMemory(ProcessHandle,
- (PVOID*)&Peb,
+ &Process->TebBlock,
0,
- &PebSize,
+ &AllocSize,
MEM_RESERVE,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
@@ -438,6 +439,8 @@
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
return(Status);
}
+ assert((ULONG_PTR) Process->TebBlock <= PEB_BASE &&
+ PEB_BASE + PAGE_SIZE <= (ULONG_PTR) Process->TebBlock + AllocSize);
Peb = (PPEB)PEB_BASE;
PebSize = PAGE_SIZE;
Status = NtAllocateVirtualMemory(ProcessHandle,
@@ -452,6 +455,8 @@
return(Status);
}
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
+ assert((PPEB) PEB_BASE == Peb && PAGE_SIZE <= PebSize);
+ Process->TebLastAllocated = (PVOID) Peb;
ViewSize = 0;
#if defined(__GNUC__)
@@ -730,6 +735,7 @@
InitializeListHead(&Process->ThreadListHead);
KeReleaseSpinLock(&PsProcessListLock, oldIrql);
+ ExInitializeFastMutex(&Process->TebLock);
Process->Pcb.State = PROCESS_STATE_ACTIVE;
/*
CVSspam 0.2.8