* Implement counting free pages in kernel heaps.
* Suggest growing when there are less than 10% free pages in the last heap. Previously it would suggest growing when there were less than three free pages, which wasn't really any good measure. In quite a few cases this could have lead to too late growing and running out of heap space. * Only panic when memory allocation fails while growing kernel heaps. Otherwise just output a message and return NULL. Even this panic is not really necessary and should be continueable, but for now I'd like to see if this situation actually happens. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26157 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0a7531ac0d
commit
a5db16fc79
@ -87,6 +87,7 @@ typedef struct heap_allocator_s {
|
||||
|
||||
uint32 bin_count;
|
||||
uint32 page_count;
|
||||
uint32 free_page_count;
|
||||
heap_page * free_pages;
|
||||
|
||||
heap_bin * bins;
|
||||
@ -237,13 +238,9 @@ dump_bin(heap_bin *bin)
|
||||
static void
|
||||
dump_allocator(heap_allocator *heap)
|
||||
{
|
||||
uint32 count = 0;
|
||||
for (heap_page *page = heap->free_pages; page != NULL; page = page->next)
|
||||
count++;
|
||||
|
||||
dprintf("allocator %p: base: 0x%08lx; size: %lu; bin_count: %lu; free_pages: %p (%lu entr%s)\n", heap,
|
||||
heap->base, heap->size, heap->bin_count, heap->free_pages, count,
|
||||
count == 1 ? "y" : "ies");
|
||||
dprintf("allocator %p: base: 0x%08lx; size: %lu; bin_count: %lu; free_pages: %p (%lu entr%s)\n",
|
||||
heap, heap->base, heap->size, heap->bin_count, heap->free_pages,
|
||||
heap->free_page_count, heap->free_page_count == 1 ? "y" : "ies");
|
||||
|
||||
for (uint32 i = 0; i < heap->bin_count; i++)
|
||||
dump_bin(&heap->bins[i]);
|
||||
@ -589,6 +586,9 @@ heap_validate_heap(heap_allocator *heap)
|
||||
freePageCount++;
|
||||
}
|
||||
|
||||
if (heap->free_page_count != freePageCount)
|
||||
panic("free page count doesn't match free page list\n");
|
||||
|
||||
// validate the page table
|
||||
uint32 usedPageCount = 0;
|
||||
for (uint32 i = 0; i < heap->page_count; i++) {
|
||||
@ -718,6 +718,7 @@ heap_attach(addr_t base, size_t size)
|
||||
heap->page_table[i].prev = &heap->page_table[i - 1];
|
||||
}
|
||||
heap->free_pages = &heap->page_table[0];
|
||||
heap->free_page_count = pageCount;
|
||||
heap->page_table[0].prev = NULL;
|
||||
|
||||
mutex_init(&heap->lock, "heap_mutex");
|
||||
@ -808,6 +809,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
|
||||
// small allocation, just grab the next free page
|
||||
heap_page *page = heap->free_pages;
|
||||
heap->free_pages = page->next;
|
||||
heap->free_page_count--;
|
||||
if (page->next)
|
||||
page->next->prev = NULL;
|
||||
|
||||
@ -872,6 +874,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
|
||||
page->free_list = NULL;
|
||||
page->allocation_id = (uint16)first;
|
||||
}
|
||||
heap->free_page_count -= pageCount;
|
||||
|
||||
#if KERNEL_HEAP_LEAK_CHECK
|
||||
heap_leak_check_info *info = (heap_leak_check_info *)(heap->base
|
||||
@ -929,10 +932,8 @@ heap_memalign(heap_allocator *heap, size_t alignment, size_t size,
|
||||
|
||||
if (heap->next == NULL && shouldGrow) {
|
||||
// suggest growing if we are the last heap and we have
|
||||
// less than three free pages left
|
||||
*shouldGrow = (heap->free_pages == NULL
|
||||
|| heap->free_pages->next == NULL
|
||||
|| heap->free_pages->next->next == NULL);
|
||||
// less than 10% free pages
|
||||
*shouldGrow = heap->free_page_count < heap->page_count / 10;
|
||||
}
|
||||
|
||||
#if KERNEL_HEAP_LEAK_CHECK
|
||||
@ -1029,6 +1030,7 @@ heap_free(heap_allocator *heap, void *address)
|
||||
heap_unlink_page(page, &bin->page_list);
|
||||
page->in_use = 0;
|
||||
heap_link_page(page, &heap->free_pages);
|
||||
heap->free_page_count++;
|
||||
} else if (page->free_count == 1) {
|
||||
// we need to add ourselfs to the page list of the bin
|
||||
heap_link_page(page, &bin->page_list);
|
||||
@ -1066,6 +1068,7 @@ heap_free(heap_allocator *heap, void *address)
|
||||
|
||||
// return it to the free list
|
||||
heap_link_page(&page[i], &heap->free_pages);
|
||||
heap->free_page_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1431,7 +1434,10 @@ malloc_nogrow(size_t size)
|
||||
}
|
||||
|
||||
// no memory available
|
||||
panic("heap: all heaps have run out of memory\n");
|
||||
if (thread_get_current_thread_id() == sHeapGrowThread)
|
||||
panic("heap: all heaps have run out of memory while growing\n");
|
||||
else
|
||||
dprintf("heap: all heaps have run out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user