Implement sub-allocation of small requests
authorGé van Geldorp <ge@gse.nl>
Wed, 25 May 2005 22:36:35 +0000 (22:36 +0000)
committerGé van Geldorp <ge@gse.nl>
Wed, 25 May 2005 22:36:35 +0000 (22:36 +0000)
svn path=/trunk/; revision=15497

reactos/boot/freeldr/freeldr/freeldr.c
reactos/boot/freeldr/freeldr/mm/mm.c

index 05913e5..54e8638 100644 (file)
@@ -35,7 +35,7 @@ VOID BootMain(char *CmdLine)
 
        DebugInit();
 
-       DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x BootPartition = %d\n", BootDrive, BootPartition));
+       DbgPrint((DPRINT_WARNING, "BootMain() called.\n"));
 
        if (!MmInitializeMemoryManager())
        {
index 402069a..6b81d8e 100644 (file)
@@ -36,10 +36,30 @@ VOID                DecrementAllocationCount(VOID);
 VOID           MemAllocTest(VOID);
 #endif // DEBUG
 
+/*
+ * Hack alert
+ * Normally, we allocate whole pages. This is ofcourse wastefull for small
+ * allocations (a few bytes). So, for small allocations (smaller than a page)
+ * we sub-allocate. When the first small allocation is done, a page is
+ * requested. We keep a pointer to that page in SubAllocationPage. The alloc
+ * is satisfied by returning a pointer to the beginning of the page. We also
+ * keep track of how many bytes are still available in the page in SubAllocationRest.
+ * When the next small request comes in, we try to allocate it just after the
+ * memory previously allocated. If it won't fit, we allocate a new page and
+ * the whole process starts again.
+ * Note that suballocations are done back-to-back, there's no bookkeeping at all.
+ * That also means that we cannot really free suballocations. So, when a free is
+ * done and it is determined that this might be a free of a sub-allocation, we
+ * just no-op the free.
+ * Perhaps we should use the heap routines from ntdll here.
+ */
+static PVOID    SubAllocationPage = NULL;
+static unsigned SubAllocationRest = 0;
+
 PVOID MmAllocateMemory(ULONG MemorySize)
 {
-       ULONG           PagesNeeded;
-       ULONG           FirstFreePageFromEnd;
+       ULONG   PagesNeeded;
+       ULONG   FirstFreePageFromEnd;
        PVOID   MemPointer;
 
        if (MemorySize == 0)
@@ -49,6 +69,14 @@ PVOID MmAllocateMemory(ULONG MemorySize)
                return NULL;
        }
 
+       MemorySize = ROUND_UP(MemorySize, 4);
+       if (MemorySize <= SubAllocationRest)
+       {
+               MemPointer = SubAllocationPage + MM_PAGE_SIZE - SubAllocationRest;
+               SubAllocationRest -= MemorySize;
+               return MemPointer;
+       }
+
        // Find out how many blocks it will take to
        // satisfy this allocation
        PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
@@ -76,6 +104,13 @@ PVOID MmAllocateMemory(ULONG MemorySize)
        FreePagesInLookupTable -= PagesNeeded;
        MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
 
+       if (MemorySize < MM_PAGE_SIZE)
+       {
+               SubAllocationPage = MemPointer;
+               SubAllocationRest = MM_PAGE_SIZE - MemorySize;
+       }
+               
+
 #ifdef DEBUG
        IncrementAllocationCount();
        DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
@@ -235,6 +270,13 @@ VOID MmFreeMemory(PVOID MemoryPointer)
 
 #endif
 
+       /* If this allocation is only a single page, it could be a sub-allocated page.
+        * Just don't free it */
+       if (1 == PageCount)
+       {
+               return;
+       }
+
        // Loop through our array and mark all the
        // blocks as free
        for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)