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:
+29
-24
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user