Confusion Regarding JamesM's Heap
Posted: Thu Apr 09, 2009 4:44 am
I know that JamesM has said his heap isn't the best around and he has written a better one, but still I wanted to ask you a question regarding it. There's something in the code that confuses me and I've only noticed it after countless hours of debugging my code. While testing my memory, I noticed that after a while I get a page-fault. It occurs after the heap starts expanding itself because it's too small. What I've noticed in the code is this (my version of the code):
And so on. Okay, the heap needs to expand itself and that's what the call there does. But if we enter the function that expands the heap:
Okay, so we need to make sure the expansion to the heap is also page-aligned. But what does 'GetPage' do when it needs to create a page?
It calls allocate all over again! Allocation will go through the memory manager and call HeapAlloc to get that memory (and because the heap has already been created, it won't use a placement address but the HeapAlloc function). The call to HeapAlloc will result in the heap trying to expand itself again, AGAIN going through the ExpandHeap function, GetPage, MM->AllocAlignGetPhys, ...
Am I making a mistake somewhere, or is this an infinite loop? Setting debug log prints only acknowledges what I'm thinking.
Thanks for your advice,
Creature
Code: Select all
void *HeapAlloc(unsigned size, bool pageAlign, Heap *heap)
{
/* Size including the header and footer. */
unsigned RealSize = size + sizeof(HeapHeader) + sizeof(HeapFooter);
int i = GetSmallestHole(RealSize, pageAlign, heap);
/* No hole found? */
if(i == -1)
{
unsigned OldLength = heap->EndAddress - heap->StartAddress;
unsigned OldEndAddress = heap->EndAddress;
/* Make the heap larger, return 0 if failed to prevent going past the maximum address. */
if(ExpandHeap(heap, OldLength + RealSize) == -1)
return 0;
//...
Code: Select all
static int ExpandHeap(Heap *heap, unsigned newSize)
{
//...
/* Make sure there are pages present at the new addresses (start at the heap ending address). */
for(unsigned i(heap->EndAddress); i < heap->StartAddress + newSize; i += HEAP_PAGESIZE)
AllocateFrame(GetPage(i, true, KernelDir), heap->Supervisor? 1 : 0, heap->ReadOnly? 0 : 1);
//...
}
Code: Select all
directory->PageTables[TableID] = (PageTable *) MM->AllocAlignGetPhys(sizeof(PageTable), &PhysAddr);
Am I making a mistake somewhere, or is this an infinite loop? Setting debug log prints only acknowledges what I'm thinking.
Thanks for your advice,
Creature