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
This commit is contained in:
Michael Lotz 2008-07-02 00:59:32 +00:00
parent 396f6e29ee
commit 0aad734230

View File

@ -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));