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:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, Michael Lotz, [email protected].
|
||||
* Copyright 2008-2009, Michael Lotz, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2002-2006, Axel Dörfler, [email protected].
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user