mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implement sub-allocation of small requests
svn path=/trunk/; revision=15497
This commit is contained in:
parent
fcb49212d9
commit
d670d4f7e6
2 changed files with 45 additions and 3 deletions
|
@ -35,7 +35,7 @@ VOID BootMain(char *CmdLine)
|
||||||
|
|
||||||
DebugInit();
|
DebugInit();
|
||||||
|
|
||||||
DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x BootPartition = %d\n", BootDrive, BootPartition));
|
DbgPrint((DPRINT_WARNING, "BootMain() called.\n"));
|
||||||
|
|
||||||
if (!MmInitializeMemoryManager())
|
if (!MmInitializeMemoryManager())
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,10 +36,30 @@ VOID DecrementAllocationCount(VOID);
|
||||||
VOID MemAllocTest(VOID);
|
VOID MemAllocTest(VOID);
|
||||||
#endif // DEBUG
|
#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)
|
PVOID MmAllocateMemory(ULONG MemorySize)
|
||||||
{
|
{
|
||||||
ULONG PagesNeeded;
|
ULONG PagesNeeded;
|
||||||
ULONG FirstFreePageFromEnd;
|
ULONG FirstFreePageFromEnd;
|
||||||
PVOID MemPointer;
|
PVOID MemPointer;
|
||||||
|
|
||||||
if (MemorySize == 0)
|
if (MemorySize == 0)
|
||||||
|
@ -49,6 +69,14 @@ PVOID MmAllocateMemory(ULONG MemorySize)
|
||||||
return NULL;
|
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
|
// Find out how many blocks it will take to
|
||||||
// satisfy this allocation
|
// satisfy this allocation
|
||||||
PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
|
PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
|
||||||
|
@ -76,6 +104,13 @@ PVOID MmAllocateMemory(ULONG MemorySize)
|
||||||
FreePagesInLookupTable -= PagesNeeded;
|
FreePagesInLookupTable -= PagesNeeded;
|
||||||
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
|
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
|
||||||
|
|
||||||
|
if (MemorySize < MM_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
SubAllocationPage = MemPointer;
|
||||||
|
SubAllocationRest = MM_PAGE_SIZE - MemorySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
IncrementAllocationCount();
|
IncrementAllocationCount();
|
||||||
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
|
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
|
#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
|
// Loop through our array and mark all the
|
||||||
// blocks as free
|
// blocks as free
|
||||||
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
|
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
|
||||||
|
|
Loading…
Reference in a new issue