Make the all_areas list ordered by base and take advantage of this ordering
when looking up the target area on free(). This makes free() scale better with large area counts, as the lookup can abort early when it knows that no area below the only candidate can contain the address. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26258 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a8f9741c8c
commit
dde0ba6223
@ -641,7 +641,7 @@ heap_validate_heap(heap_allocator *heap)
|
||||
uint32 totalPageCount = 0;
|
||||
uint32 totalFreePageCount = 0;
|
||||
heap_area *area = heap->all_areas;
|
||||
while (area) {
|
||||
while (area != NULL) {
|
||||
// validate the free pages list
|
||||
uint32 freePageCount = 0;
|
||||
heap_page *lastPage = NULL;
|
||||
@ -693,9 +693,9 @@ heap_validate_heap(heap_allocator *heap)
|
||||
area = heap->areas;
|
||||
heap_area *lastArea = NULL;
|
||||
uint32 lastFreeCount = 0;
|
||||
while (area) {
|
||||
while (area != NULL) {
|
||||
if (area->free_page_count < lastFreeCount)
|
||||
panic("ordering of area list broken\n");
|
||||
panic("size ordering of area list broken\n");
|
||||
|
||||
if (area->prev != lastArea)
|
||||
panic("area list entry has invalid prev link\n");
|
||||
@ -705,6 +705,16 @@ heap_validate_heap(heap_allocator *heap)
|
||||
area = area->next;
|
||||
}
|
||||
|
||||
lastArea = NULL;
|
||||
area = heap->all_areas;
|
||||
while (area != NULL) {
|
||||
if (lastArea != NULL && lastArea->base < area->base)
|
||||
panic("base ordering of all_areas list broken\n");
|
||||
|
||||
lastArea = area;
|
||||
area = area->all_next;
|
||||
}
|
||||
|
||||
// validate the bins
|
||||
for (uint32 i = 0; i < heap->bin_count; i++) {
|
||||
heap_bin *bin = &heap->bins[i];
|
||||
@ -845,8 +855,19 @@ heap_add_area(heap_allocator *heap, area_id areaID, addr_t base, size_t size)
|
||||
area->prev = lastArea;
|
||||
}
|
||||
|
||||
area->all_next = heap->all_areas;
|
||||
heap->all_areas = area;
|
||||
// insert this area in the all_areas list so it stays ordered by base
|
||||
if (heap->all_areas == NULL || heap->all_areas->base < area->base) {
|
||||
area->all_next = heap->all_areas;
|
||||
heap->all_areas = area;
|
||||
} else {
|
||||
heap_area *insert = heap->all_areas;
|
||||
while (insert->all_next && insert->all_next->base > area->base)
|
||||
insert = insert->all_next;
|
||||
|
||||
area->all_next = insert->all_next;
|
||||
insert->all_next = area;
|
||||
}
|
||||
|
||||
heap->total_pages += area->page_count;
|
||||
heap->total_free_pages += area->free_page_count;
|
||||
|
||||
@ -1283,9 +1304,19 @@ heap_free(heap_allocator *heap, void *address)
|
||||
|
||||
heap_area *area = heap->all_areas;
|
||||
while (area) {
|
||||
if ((addr_t)address >= area->base
|
||||
&& (addr_t)address < area->base + area->size)
|
||||
// since the all_areas list is ordered by base with the biggest
|
||||
// base at the top, we need only find the first area with a base
|
||||
// smaller than our address to become our only candidate for freeing
|
||||
if (area->base <= (addr_t)address) {
|
||||
if ((addr_t)address >= area->base + area->size) {
|
||||
// the only candidate area doesn't contain the address,
|
||||
// set it to NULL so we return below (none of the other areas
|
||||
// can contain the address as the list is ordered)
|
||||
area = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
area = area->all_next;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user