mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-03 17:24:39 +00:00
mem: Fix Buddy_Allocator size calculation to truly include alignment
This didn't take into account the size of the header plus the size of the allocation itself by virtue of `align_forward_uint`; this could result in no change if `size` was equal to `b.alignment` because the number is aligned, and if `actual_size` and `size` ended up being equal, no additional space would be requested. This meant that a block would end up being allocated on top of its buddy's head. Fixes #3435
This commit is contained in:
@@ -2247,12 +2247,14 @@ Get required block size to fit in the allocation as well as the alignment paddin
|
||||
*/
|
||||
@(require_results)
|
||||
buddy_block_size_required :: proc(b: ^Buddy_Allocator, size: uint) -> uint {
|
||||
size := size
|
||||
actual_size := b.alignment
|
||||
size += size_of(Buddy_Block)
|
||||
size = align_forward_uint(size, b.alignment)
|
||||
for size > actual_size {
|
||||
actual_size <<= 1
|
||||
assert(size > 0)
|
||||
// NOTE: `size_of(Buddy_Block)` will be accounted for in `b.alignment`.
|
||||
// This calculation is also previously guarded against being given a `size`
|
||||
// 0 by `buddy_allocator_alloc_bytes_non_zeroed` checking for that.
|
||||
actual_size := b.alignment + size
|
||||
if intrinsics.count_ones(actual_size) != 1 {
|
||||
// We're not a power of two. Let's fix that.
|
||||
actual_size = 1 << (size_of(uint) * 8 - intrinsics.count_leading_zeros(actual_size))
|
||||
}
|
||||
return actual_size
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user