Commit in reactos/ntoskrnl on MAIN
include/internal/ps.h+5-11.69 -> 1.70
                /mm.h+41.89 -> 1.90
mm/anonmem.c+2-21.32 -> 1.33
  /marea.c+43-121.67 -> 1.68
ps/create.c+58-331.81 -> 1.82
  /process.c+11-51.143 -> 1.144
+123-53
6 modified files
Don't use more than a single page for a TEB

reactos/ntoskrnl/include/internal
ps.h 1.69 -> 1.70
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
mm.h 1.89 -> 1.90
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
anonmem.c 1.32 -> 1.33
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
marea.c 1.67 -> 1.68
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
create.c 1.81 -> 1.82
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
process.c 1.143 -> 1.144
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