Changeset 26258

Show
Ignore:
Timestamp:
07/04/08 21:12:34 (5 months ago)
Author:
mmlr
Message:

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.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • haiku/trunk/src/system/kernel/heap.cpp

    r26252 r26258  
    642642        uint32 totalFreePageCount = 0; 
    643643        heap_area *area = heap->all_areas; 
    644         while (area) { 
     644        while (area != NULL) { 
    645645                // validate the free pages list 
    646646                uint32 freePageCount = 0; 
     
    694694        heap_area *lastArea = NULL; 
    695695        uint32 lastFreeCount = 0; 
    696         while (area) { 
     696        while (area != NULL) { 
    697697                if (area->free_page_count < lastFreeCount) 
    698                         panic("ordering of area list broken\n"); 
     698                        panic("size ordering of area list broken\n"); 
    699699 
    700700                if (area->prev != lastArea) 
     
    704704                lastFreeCount = area->free_page_count; 
    705705                area = area->next; 
     706        } 
     707 
     708        lastArea = NULL; 
     709        area = heap->all_areas; 
     710        while (area != NULL) { 
     711                if (lastArea != NULL && lastArea->base < area->base) 
     712                        panic("base ordering of all_areas list broken\n"); 
     713 
     714                lastArea = area; 
     715                area = area->all_next; 
    706716        } 
    707717 
     
    846856        } 
    847857 
    848         area->all_next = heap->all_areas; 
    849         heap->all_areas = area; 
     858        // insert this area in the all_areas list so it stays ordered by base 
     859        if (heap->all_areas == NULL || heap->all_areas->base < area->base) { 
     860                area->all_next = heap->all_areas; 
     861                heap->all_areas = area; 
     862        } else { 
     863                heap_area *insert = heap->all_areas; 
     864                while (insert->all_next && insert->all_next->base > area->base) 
     865                        insert = insert->all_next; 
     866 
     867                area->all_next = insert->all_next; 
     868                insert->all_next = area; 
     869        } 
     870 
    850871        heap->total_pages += area->page_count; 
    851872        heap->total_free_pages += area->free_page_count; 
     
    12841305        heap_area *area = heap->all_areas; 
    12851306        while (area) { 
    1286                 if ((addr_t)address >= area->base 
    1287                         && (addr_t)address < area->base + area->size) 
     1307                // since the all_areas list is ordered by base with the biggest 
     1308                // base at the top, we need only find the first area with a base 
     1309                // smaller than our address to become our only candidate for freeing 
     1310                if (area->base <= (addr_t)address) { 
     1311                        if ((addr_t)address >= area->base + area->size) { 
     1312                                // the only candidate area doesn't contain the address, 
     1313                                // set it to NULL so we return below (none of the other areas 
     1314                                // can contain the address as the list is ordered) 
     1315                                area = NULL; 
     1316                        } 
     1317 
    12881318                        break; 
     1319                } 
    12891320 
    12901321                area = area->all_next;