From 0aad7342300dbf1580ea14b01e1b52c36aba674f Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 2 Jul 2008 00:59:32 +0000 Subject: [PATCH] The simple alignment trick used before doesn't work with the new heap classes (it didn't really work previously anyway). The only alignment really used seems to be B_PAGE_SIZE, which happened to always work out before, because anything larger would have been allocated using individual pages anyway. Since larger bins are now available and with kernel heap leak checking enabled an allocation of B_PAGE_SIZE with B_PAGE_SIZE alignment is actually a bit bigger than B_PAGE_SIZE, it got into the 5KB bin, which didn't guarantee the alignment anymore. This would have caused a tripple fault on boot when kernel heap leak checking was enabled. The alignment is now taken into account when picking the bin for the allocation. Added a more detailed TODO as to why this isn't the best thing (wastes space) and how it could be changed if deemed necessary. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26212 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/heap.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/system/kernel/heap.cpp b/src/system/kernel/heap.cpp index cbaffd3d23..659af3d4dd 100644 --- a/src/system/kernel/heap.cpp +++ b/src/system/kernel/heap.cpp @@ -965,18 +965,23 @@ heap_memalign(heap_allocator *heap, size_t alignment, size_t size, size += sizeof(heap_leak_check_info); #endif - // ToDo: that code "aligns" the buffer because the bins are always - // aligned on their bin size - if (size < alignment) - size = alignment; - uint32 binIndex; for (binIndex = 0; binIndex < heap->bin_count; binIndex++) { - if (size <= heap->bins[binIndex].element_size) + // TODO: The alignment is done by ensuring that the element size + // of the target bin is aligned with the requested alignment. This + // has the problem that it wastes space because a better (smaller) bin + // could possibly be selected. We should pick the best bin and check + // if there is an aligned block in the free list or if a new (page + // aligned) page has to be allocated anyway. + size_t elementSize = heap->bins[binIndex].element_size; + if (size <= elementSize && (alignment == 0 + || (elementSize & (alignment - 1) == 0))) break; } void *address = heap_raw_alloc(heap, size, binIndex); + if (alignment != 0 && ((addr_t)address & (alignment - 1))) + panic("alignment not met at %p with 0x%08lx\n", address, alignment); TRACE(("memalign(): asked to allocate %lu bytes, returning pointer %p\n", size, address));