Fix errors in maintaining the area list due to assumptions that are only true

for the page list but not the area one. Since multiple pages can be allocated
at once, even an area that is not at the top of the list can become empty. In
such a case the area list would previously have lost entries. Also because
we can remove more than one page from any area, not just the top one, we may
need to move forward in the list so that it stays ordered by free pages.
+alphabranch


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32880 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2009-09-01 08:46:39 +00:00
parent 5bfffb9d94
commit 419f2d6f3e

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008, Michael Lotz, mmlr@mlotz.ch.
* Copyright 2008-2009, Michael Lotz, mmlr@mlotz.ch.
* Distributed under the terms of the MIT License.
*
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
@ -1193,10 +1193,35 @@ heap_free_pages_removed(heap_allocator *heap, heap_area *area, uint32 pageCount)
if (area->free_page_count == 0) {
// the area is now full so we remove it from the area list
heap->areas = area->next;
if (area->prev)
area->prev->next = area->next;
if (area->next)
area->next->prev = NULL;
area->next->prev = area->prev;
if (heap->areas == area)
heap->areas = area->next;
area->next = area->prev = NULL;
} else {
// we might need to move forward in the area list
if (area->prev && area->prev->free_page_count > area->free_page_count) {
// move ourselfs so the list stays ordered
heap_area *insert = area->prev;
while (insert->prev
&& insert->prev->free_page_count > area->free_page_count)
insert = insert->prev;
if (area->prev)
area->prev->next = area->next;
if (area->next)
area->next->prev = area->prev;
area->prev = insert->prev;
area->next = insert;
if (area->prev)
area->prev->next = area;
if (heap->areas == insert)
heap->areas = area;
insert->prev = area;
}
}
}