Implement sub-allocation of small requests
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/mm/mm.c
_____
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.c
--- trunk/reactos/boot/freeldr/freeldr/freeldr.c 2005-05-25
20:59:13 UTC (rev 15496)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr.c 2005-05-25
22:36:35 UTC (rev 15497)
@@ -35,7 +35,7 @@
DebugInit();
- DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x
BootPartition = %d\n", BootDrive, BootPartition));
+ DbgPrint((DPRINT_WARNING, "BootMain() called.\n"));
if (!MmInitializeMemoryManager())
{
_____
Modified: trunk/reactos/boot/freeldr/freeldr/mm/mm.c
--- trunk/reactos/boot/freeldr/freeldr/mm/mm.c 2005-05-25 20:59:13 UTC
(rev 15496)
+++ trunk/reactos/boot/freeldr/freeldr/mm/mm.c 2005-05-25 22:36:35 UTC
(rev 15497)
@@ -36,10 +36,30 @@
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 @@
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 @@
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 @@
#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++)
Show replies by date