From 63ae4569814eb8a2f7ffa5d19fbcf57d6765eb47 Mon Sep 17 00:00:00 2001 From: mevinagrise Date: Thu, 26 Mar 2026 19:59:39 +0800 Subject: [PATCH] fix: preserve merged block when frame deallocation reaches the top order --- src/frame.rs | 4 ++-- src/test.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/frame.rs b/src/frame.rs index 246ce78..f9e3e3a 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -153,18 +153,18 @@ impl FrameAllocator { // Merge free buddy lists let mut current_ptr = start_frame; 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); if self.free_list[current_class].remove(&buddy) { // Free buddy found current_ptr = min(current_ptr, buddy); current_class += 1; } else { - self.free_list[current_class].insert(current_ptr); break; } } + self.free_list[current_class].insert(current_ptr); self.allocated -= size; } } diff --git a/src/test.rs b/src/test.rs index 77c15a7..77a5ae3 100644 --- a/src/test.rs +++ b/src/test.rs @@ -211,6 +211,20 @@ fn test_frame_allocator_aligned() { ); } +#[test] +fn test_frame_allocator_merge_final_order() { + let mut frame = FrameAllocator::<2>::new(); + frame.add_frame(0, 4); + + let first = frame.alloc(2).unwrap(); + let second = frame.alloc(2).unwrap(); + + frame.dealloc(first, 2); + frame.dealloc(second, 2); + + assert_eq!(frame.alloc(2), Some(0)); +} + #[test] fn test_heap_merge_final_order() { const NUM_ORDERS: usize = 5;