diff --git a/src/lib.rs b/src/lib.rs index 334d843..f9dea8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -157,7 +157,8 @@ impl Heap { // Merge free buddy lists let mut current_ptr = ptr.as_ptr() as usize; let mut current_class = class; - while current_class < self.free_list.len() { + + while current_class < self.free_list.len() - 1 { let buddy = current_ptr ^ (1 << current_class); let mut flag = false; for block in self.free_list[current_class].iter_mut() { diff --git a/src/test.rs b/src/test.rs index b19599f..7f2e0f1 100644 --- a/src/test.rs +++ b/src/test.rs @@ -192,3 +192,34 @@ fn test_frame_allocator_aligned() { Some(16) ); } + +#[test] +fn test_heap_merge_final_order() { + const NUM_ORDERS: usize = 5; + + let backing_size = 1 << NUM_ORDERS; + let backing_layout = Layout::from_size_align(backing_size, backing_size).unwrap(); + + // create a new heap with 5 orders + let mut heap = Heap::::new(); + + // allocate host memory for use by heap + let backing_allocation = unsafe { std::alloc::alloc(backing_layout) }; + + let start = backing_allocation as usize; + let middle = unsafe { backing_allocation.add(backing_size / 2) } as usize; + let end = unsafe { backing_allocation.add(backing_size) } as usize; + + // add two contiguous ranges of memory + unsafe { heap.add_to_heap(start, middle) }; + unsafe { heap.add_to_heap(middle, end) }; + + // NUM_ORDERS - 1 is the maximum order of the heap + let layout = Layout::from_size_align(1 << (NUM_ORDERS - 1), 1).unwrap(); + + // allocation should succeed, using one of the added ranges + let alloc = heap.alloc(layout).unwrap(); + + // deallocation should not attempt to merge the two contiguous ranges as the next order does not exist + heap.dealloc(alloc, layout); +}