Remove the B_PAGE_SIZE page size and replace it by a heap->page_size. This

allows for dynamic (heap)page sizes. It's currently just set to B_PAGE_SIZE
but I'm expermienting with the creation of differently sized heaps that could
use dynamic page sizes with that.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26203 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2008-07-01 20:44:43 +00:00
parent b42c202a65
commit 8c57aefdf8
+29 -24
View File
@@ -87,6 +87,7 @@ typedef struct heap_allocator_s {
uint32 bin_count; uint32 bin_count;
uint32 page_count; uint32 page_count;
uint32 page_size;
uint32 free_page_count; uint32 free_page_count;
heap_page * free_pages; heap_page * free_pages;
@@ -321,7 +322,7 @@ dump_allocations(int argc, char **argv)
if (!page->in_use) if (!page->in_use)
continue; continue;
addr_t base = heap->base + i * B_PAGE_SIZE; addr_t base = heap->base + i * heap->page_size;
if (page->bin_index < heap->bin_count) { if (page->bin_index < heap->bin_count) {
// page is used by a small allocation bin // page is used by a small allocation bin
uint32 elementCount = page->empty_index; uint32 elementCount = page->empty_index;
@@ -366,8 +367,8 @@ dump_allocations(int argc, char **argv)
&& heap->page_table[i + pageCount].allocation_id == page->allocation_id) && heap->page_table[i + pageCount].allocation_id == page->allocation_id)
pageCount++; pageCount++;
info = (heap_leak_check_info *)(base + pageCount * B_PAGE_SIZE info = (heap_leak_check_info *)(base + pageCount
- sizeof(heap_leak_check_info)); * heap->page_size - sizeof(heap_leak_check_info));
if ((team == -1 || info->team == team) if ((team == -1 || info->team == team)
&& (thread == -1 || info->thread == thread) && (thread == -1 || info->thread == thread)
@@ -461,7 +462,7 @@ dump_allocations_per_caller(int argc, char **argv)
if (!page->in_use) if (!page->in_use)
continue; continue;
addr_t base = heap->base + i * B_PAGE_SIZE; addr_t base = heap->base + i * heap->page_size;
if (page->bin_index < heap->bin_count) { if (page->bin_index < heap->bin_count) {
// page is used by a small allocation bin // page is used by a small allocation bin
uint32 elementCount = page->empty_index; uint32 elementCount = page->empty_index;
@@ -501,8 +502,8 @@ dump_allocations_per_caller(int argc, char **argv)
&& heap->page_table[i + pageCount].allocation_id == page->allocation_id) && heap->page_table[i + pageCount].allocation_id == page->allocation_id)
pageCount++; pageCount++;
info = (heap_leak_check_info *)(base + pageCount * B_PAGE_SIZE info = (heap_leak_check_info *)(base + pageCount
- sizeof(heap_leak_check_info)); * heap->page_size - sizeof(heap_leak_check_info));
caller_info* callerInfo = get_caller_info(info->caller); caller_info* callerInfo = get_caller_info(info->caller);
if (callerInfo == NULL) { if (callerInfo == NULL) {
@@ -636,10 +637,10 @@ heap_validate_heap(heap_allocator *heap)
// validate the free list // validate the free list
uint32 freeSlotsCount = 0; uint32 freeSlotsCount = 0;
addr_t *element = page->free_list; addr_t *element = page->free_list;
addr_t pageBase = heap->base + page->index * B_PAGE_SIZE; addr_t pageBase = heap->base + page->index * heap->page_size;
while (element) { while (element) {
if ((addr_t)element < pageBase if ((addr_t)element < pageBase
|| (addr_t)element >= pageBase + B_PAGE_SIZE) || (addr_t)element >= pageBase + heap->page_size)
panic("free list entry out of page range\n"); panic("free list entry out of page range\n");
if (((addr_t)element - pageBase) % bin->element_size != 0) if (((addr_t)element - pageBase) % bin->element_size != 0)
@@ -681,6 +682,7 @@ heap_attach(addr_t base, size_t size)
size_t binSizes[] = { 8, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 1024, 2048, B_PAGE_SIZE }; size_t binSizes[] = { 8, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 1024, 2048, B_PAGE_SIZE };
uint32 binCount = sizeof(binSizes) / sizeof(binSizes[0]); uint32 binCount = sizeof(binSizes) / sizeof(binSizes[0]);
heap->page_size = B_PAGE_SIZE;
heap->bin_count = binCount; heap->bin_count = binCount;
heap->bins = (heap_bin *)base; heap->bins = (heap_bin *)base;
base += binCount * sizeof(heap_bin); base += binCount * sizeof(heap_bin);
@@ -689,11 +691,11 @@ heap_attach(addr_t base, size_t size)
for (uint32 i = 0; i < binCount; i++) { for (uint32 i = 0; i < binCount; i++) {
heap_bin *bin = &heap->bins[i]; heap_bin *bin = &heap->bins[i];
bin->element_size = binSizes[i]; bin->element_size = binSizes[i];
bin->max_free_count = B_PAGE_SIZE / binSizes[i]; bin->max_free_count = heap->page_size / binSizes[i];
bin->page_list = NULL; bin->page_list = NULL;
} }
uint32 pageCount = size / B_PAGE_SIZE; uint32 pageCount = size / heap->page_size;
size_t pageTableSize = pageCount * sizeof(heap_page); size_t pageTableSize = pageCount * sizeof(heap_page);
heap->page_table = (heap_page *)base; heap->page_table = (heap_page *)base;
base += pageTableSize; base += pageTableSize;
@@ -704,7 +706,7 @@ heap_attach(addr_t base, size_t size)
heap->size = (size_t)(size / B_PAGE_SIZE) * B_PAGE_SIZE; heap->size = (size_t)(size / B_PAGE_SIZE) * B_PAGE_SIZE;
// now we know the real page count // now we know the real page count
pageCount = heap->size / B_PAGE_SIZE; pageCount = heap->size / heap->page_size;
heap->page_count = pageCount; heap->page_count = pageCount;
// zero out the heap alloc table at the base of the heap // zero out the heap alloc table at the base of the heap
@@ -773,7 +775,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
page->free_list = (addr_t *)*page->free_list; page->free_list = (addr_t *)*page->free_list;
} else { } else {
// the page hasn't been fully allocated so use the next empty_index // the page hasn't been fully allocated so use the next empty_index
address = (void *)(heap->base + page->index * B_PAGE_SIZE address = (void *)(heap->base + page->index * heap->page_size
+ page->empty_index * bin->element_size); + page->empty_index * bin->element_size);
page->empty_index++; page->empty_index++;
} }
@@ -827,7 +829,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
#if KERNEL_HEAP_LEAK_CHECK #if KERNEL_HEAP_LEAK_CHECK
heap_leak_check_info *info = (heap_leak_check_info *)(heap->base heap_leak_check_info *info = (heap_leak_check_info *)(heap->base
+ page->index * B_PAGE_SIZE + bin->element_size + page->index * heap->page_size + bin->element_size
- sizeof(heap_leak_check_info)); - sizeof(heap_leak_check_info));
info->size = size - sizeof(heap_leak_check_info); info->size = size - sizeof(heap_leak_check_info);
info->thread = (kernel_startup ? 0 : thread_get_current_thread_id()); info->thread = (kernel_startup ? 0 : thread_get_current_thread_id());
@@ -836,7 +838,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
#endif #endif
// we return the first slot in this page // we return the first slot in this page
return (void *)(heap->base + page->index * B_PAGE_SIZE); return (void *)(heap->base + page->index * heap->page_size);
} }
// large allocation, we must search for contiguous slots // large allocation, we must search for contiguous slots
@@ -849,7 +851,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
} }
if (first > 0) { if (first > 0) {
if ((1 + i - first) * B_PAGE_SIZE >= size) { if ((1 + i - first) * heap->page_size >= size) {
found = true; found = true;
break; break;
} }
@@ -862,7 +864,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
return NULL; return NULL;
} }
uint32 pageCount = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE; uint32 pageCount = (size + heap->page_size - 1) / heap->page_size;
for (uint32 i = first; i < first + pageCount; i++) { for (uint32 i = first; i < first + pageCount; i++) {
heap_page *page = &heap->page_table[i]; heap_page *page = &heap->page_table[i];
page->in_use = 1; page->in_use = 1;
@@ -878,13 +880,13 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
#if KERNEL_HEAP_LEAK_CHECK #if KERNEL_HEAP_LEAK_CHECK
heap_leak_check_info *info = (heap_leak_check_info *)(heap->base heap_leak_check_info *info = (heap_leak_check_info *)(heap->base
+ (first + pageCount) * B_PAGE_SIZE - sizeof(heap_leak_check_info)); + (first + pageCount) * heap->page_size - sizeof(heap_leak_check_info));
info->size = size - sizeof(heap_leak_check_info); info->size = size - sizeof(heap_leak_check_info);
info->thread = (kernel_startup ? 0 : thread_get_current_thread_id()); info->thread = (kernel_startup ? 0 : thread_get_current_thread_id());
info->team = (kernel_startup ? 0 : team_get_current_team_id()); info->team = (kernel_startup ? 0 : team_get_current_team_id());
info->caller = get_caller(); info->caller = get_caller();
#endif #endif
return (void *)(heap->base + first * B_PAGE_SIZE); return (void *)(heap->base + first * heap->page_size);
} }
@@ -976,7 +978,8 @@ heap_free(heap_allocator *heap, void *address)
TRACE(("free(): asked to free at ptr = %p\n", address)); TRACE(("free(): asked to free at ptr = %p\n", address));
heap_page *page = &heap->page_table[((addr_t)address - heap->base) / B_PAGE_SIZE]; heap_page *page = &heap->page_table[((addr_t)address - heap->base)
/ heap->page_size];
TRACE(("free(): page %p: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count)); TRACE(("free(): page %p: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count));
@@ -989,7 +992,8 @@ heap_free(heap_allocator *heap, void *address)
if (page->bin_index < heap->bin_count) { if (page->bin_index < heap->bin_count) {
// small allocation // small allocation
heap_bin *bin = &heap->bins[page->bin_index]; heap_bin *bin = &heap->bins[page->bin_index];
if (((addr_t)address - heap->base - page->index * B_PAGE_SIZE) % bin->element_size != 0) { if (((addr_t)address - heap->base - page->index
* heap->page_size) % bin->element_size != 0) {
panic("free(): passed invalid pointer %p supposed to be in bin for element size %ld\n", address, bin->element_size); panic("free(): passed invalid pointer %p supposed to be in bin for element size %ld\n", address, bin->element_size);
mutex_unlock(&heap->lock); mutex_unlock(&heap->lock);
return B_ERROR; return B_ERROR;
@@ -1091,7 +1095,8 @@ heap_realloc(heap_allocator *heap, void *address, void **newAddress,
mutex_lock(&heap->lock); mutex_lock(&heap->lock);
TRACE(("realloc(address = %p, newSize = %lu)\n", address, newSize)); TRACE(("realloc(address = %p, newSize = %lu)\n", address, newSize));
heap_page *page = &heap->page_table[((addr_t)address - heap->base) / B_PAGE_SIZE]; heap_page *page = &heap->page_table[((addr_t)address - heap->base)
/ heap->page_size];
if (page->bin_index > heap->bin_count) { if (page->bin_index > heap->bin_count) {
panic("realloc(): page %p: invalid bin_index %d\n", page, page->bin_index); panic("realloc(): page %p: invalid bin_index %d\n", page, page->bin_index);
mutex_unlock(&heap->lock); mutex_unlock(&heap->lock);
@@ -1111,14 +1116,14 @@ heap_realloc(heap_allocator *heap, void *address, void **newAddress,
// this was a large allocation // this was a large allocation
uint32 allocationID = page->allocation_id; uint32 allocationID = page->allocation_id;
uint32 maxPages = heap->page_count - page->index; uint32 maxPages = heap->page_count - page->index;
maxSize = B_PAGE_SIZE; maxSize = heap->page_size;
for (uint32 i = 1; i < maxPages; i++) { for (uint32 i = 1; i < maxPages; i++) {
if (!page[i].in_use || page[i].bin_index != heap->bin_count if (!page[i].in_use || page[i].bin_index != heap->bin_count
|| page[i].allocation_id != allocationID) || page[i].allocation_id != allocationID)
break; break;
minSize += B_PAGE_SIZE; minSize += heap->page_size;
maxSize += B_PAGE_SIZE; maxSize += heap->page_size;
} }
} }