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 page_count;
uint32 page_size;
uint32 free_page_count;
heap_page * free_pages;
@@ -321,7 +322,7 @@ dump_allocations(int argc, char **argv)
if (!page->in_use)
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) {
// page is used by a small allocation bin
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)
pageCount++;
info = (heap_leak_check_info *)(base + pageCount * B_PAGE_SIZE
- sizeof(heap_leak_check_info));
info = (heap_leak_check_info *)(base + pageCount
* heap->page_size - sizeof(heap_leak_check_info));
if ((team == -1 || info->team == team)
&& (thread == -1 || info->thread == thread)
@@ -461,7 +462,7 @@ dump_allocations_per_caller(int argc, char **argv)
if (!page->in_use)
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) {
// page is used by a small allocation bin
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)
pageCount++;
info = (heap_leak_check_info *)(base + pageCount * B_PAGE_SIZE
- sizeof(heap_leak_check_info));
info = (heap_leak_check_info *)(base + pageCount
* heap->page_size - sizeof(heap_leak_check_info));
caller_info* callerInfo = get_caller_info(info->caller);
if (callerInfo == NULL) {
@@ -636,10 +637,10 @@ heap_validate_heap(heap_allocator *heap)
// validate the free list
uint32 freeSlotsCount = 0;
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) {
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");
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 };
uint32 binCount = sizeof(binSizes) / sizeof(binSizes[0]);
heap->page_size = B_PAGE_SIZE;
heap->bin_count = binCount;
heap->bins = (heap_bin *)base;
base += binCount * sizeof(heap_bin);
@@ -689,11 +691,11 @@ heap_attach(addr_t base, size_t size)
for (uint32 i = 0; i < binCount; i++) {
heap_bin *bin = &heap->bins[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;
}
uint32 pageCount = size / B_PAGE_SIZE;
uint32 pageCount = size / heap->page_size;
size_t pageTableSize = pageCount * sizeof(heap_page);
heap->page_table = (heap_page *)base;
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;
// now we know the real page count
pageCount = heap->size / B_PAGE_SIZE;
pageCount = heap->size / heap->page_size;
heap->page_count = pageCount;
// 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;
} else {
// 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++;
}
@@ -827,7 +829,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
#if KERNEL_HEAP_LEAK_CHECK
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));
info->size = size - sizeof(heap_leak_check_info);
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
// 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
@@ -849,7 +851,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
}
if (first > 0) {
if ((1 + i - first) * B_PAGE_SIZE >= size) {
if ((1 + i - first) * heap->page_size >= size) {
found = true;
break;
}
@@ -862,7 +864,7 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
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++) {
heap_page *page = &heap->page_table[i];
page->in_use = 1;
@@ -878,13 +880,13 @@ heap_raw_alloc(heap_allocator *heap, size_t size, uint32 binIndex)
#if KERNEL_HEAP_LEAK_CHECK
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->thread = (kernel_startup ? 0 : thread_get_current_thread_id());
info->team = (kernel_startup ? 0 : team_get_current_team_id());
info->caller = get_caller();
#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));
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));
@@ -989,7 +992,8 @@ heap_free(heap_allocator *heap, void *address)
if (page->bin_index < heap->bin_count) {
// small allocation
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);
mutex_unlock(&heap->lock);
return B_ERROR;
@@ -1091,7 +1095,8 @@ heap_realloc(heap_allocator *heap, void *address, void **newAddress,
mutex_lock(&heap->lock);
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) {
panic("realloc(): page %p: invalid bin_index %d\n", page, page->bin_index);
mutex_unlock(&heap->lock);
@@ -1111,14 +1116,14 @@ heap_realloc(heap_allocator *heap, void *address, void **newAddress,
// this was a large allocation
uint32 allocationID = page->allocation_id;
uint32 maxPages = heap->page_count - page->index;
maxSize = B_PAGE_SIZE;
maxSize = heap->page_size;
for (uint32 i = 1; i < maxPages; i++) {
if (!page[i].in_use || page[i].bin_index != heap->bin_count
|| page[i].allocation_id != allocationID)
break;
minSize += B_PAGE_SIZE;
maxSize += B_PAGE_SIZE;
minSize += heap->page_size;
maxSize += heap->page_size;
}
}