Page 1 of 1

Confusion Regarding JamesM's Heap

Posted: Thu Apr 09, 2009 4:44 am
by Creature
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):

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;

        //...
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:

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);

   //...
}
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?

Code: Select all

directory->PageTables[TableID] = (PageTable *) MM->AllocAlignGetPhys(sizeof(PageTable), &PhysAddr);
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