From 9c15adf6c87895ea6d3b10a543d906e155572e3f Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 25 May 2023 19:25:26 +0100 Subject: [PATCH 1/2] only normalise the relevant blocks --- agb/src/agb_alloc/block_allocator.rs | 50 ++++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/agb/src/agb_alloc/block_allocator.rs b/agb/src/agb_alloc/block_allocator.rs index 921a4308..d5893d05 100644 --- a/agb/src/agb_alloc/block_allocator.rs +++ b/agb/src/agb_alloc/block_allocator.rs @@ -133,29 +133,25 @@ impl BlockAllocatorInner { } /// Merges blocks together to create a normalised list - unsafe fn normalise(&mut self) { - let mut list_ptr = &mut self.state.first_free_block; - - while let Some(mut current) = list_ptr { - if let Some(next_elem) = current.as_mut().next { - let difference = next_elem + unsafe fn normalise(&mut self, point_to_normalise: *mut Block) { + unsafe fn normalise_block(block_to_normalise: &mut Block) { + if let Some(next_block) = block_to_normalise.next { + let difference = next_block .as_ptr() .cast::() - .offset_from(current.as_ptr().cast::()); - let usize_difference: usize = difference - .try_into() - .expect("distances in alloc'd blocks must be positive"); - - if usize_difference == current.as_mut().size { - let current = current.as_mut(); - let next = next_elem.as_ref(); - - current.size += next.size; - current.next = next.next; - continue; + .offset_from((block_to_normalise as *mut Block).cast::()); + if difference == block_to_normalise.size as isize { + let next = next_block.as_ref(); + block_to_normalise.next = next.next; + block_to_normalise.size += next.size; + normalise_block(block_to_normalise); } } - list_ptr = &mut current.as_mut().next; + } + + normalise_block(&mut *point_to_normalise); + if let Some(mut next_block) = (*point_to_normalise).next { + normalise_block(next_block.as_mut()); } } @@ -279,8 +275,10 @@ impl BlockAllocatorInner { } pub unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - self.dealloc_no_normalise(ptr, layout); - self.normalise(); + let point_to_normalise = self.dealloc_no_normalise(ptr, layout); + if let Some(block_to_normalise) = *point_to_normalise { + self.normalise(block_to_normalise.as_ptr()); + } } /// Returns a reference to the pointer to the next block @@ -305,11 +303,16 @@ impl BlockAllocatorInner { } } - pub unsafe fn dealloc_no_normalise(&mut self, ptr: *mut u8, layout: Layout) { + pub unsafe fn dealloc_no_normalise( + &mut self, + ptr: *mut u8, + layout: Layout, + ) -> *mut Option> { let new_layout = Block::either_layout(layout).pad_to_align(); // note that this is a reference to a pointer let mut list_ptr = &mut self.state.first_free_block; + let mut list_ptr_prev: *mut Option> = list_ptr; // This searches the free list until it finds a block further along // than the block that is being freed. The newly freed block is then @@ -327,6 +330,7 @@ impl BlockAllocatorInner { *list_ptr = NonNull::new(ptr.cast()).map(SendNonNull); break; } + list_ptr_prev = list_ptr; list_ptr = &mut current_block.as_mut().next; } None => { @@ -341,6 +345,8 @@ impl BlockAllocatorInner { } } } + + list_ptr_prev } } From 7e111e03273c1925716e4b9b28c9a9c97d60d90e Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 25 May 2023 19:30:38 +0100 Subject: [PATCH 2/2] remove unused import --- agb/src/agb_alloc/block_allocator.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/agb/src/agb_alloc/block_allocator.rs b/agb/src/agb_alloc/block_allocator.rs index d5893d05..c65e4c96 100644 --- a/agb/src/agb_alloc/block_allocator.rs +++ b/agb/src/agb_alloc/block_allocator.rs @@ -6,7 +6,6 @@ use core::alloc::{Allocator, GlobalAlloc, Layout}; use core::cell::UnsafeCell; -use core::convert::TryInto; use core::ptr::NonNull; use super::bump_allocator::{BumpAllocatorInner, StartEnd};