only normalise the relevant blocks

This commit is contained in:
Corwin 2023-05-25 19:25:26 +01:00
parent 1b687b787d
commit 9c15adf6c8
No known key found for this signature in database

View file

@ -133,29 +133,25 @@ impl BlockAllocatorInner {
} }
/// Merges blocks together to create a normalised list /// Merges blocks together to create a normalised list
unsafe fn normalise(&mut self) { unsafe fn normalise(&mut self, point_to_normalise: *mut Block) {
let mut list_ptr = &mut self.state.first_free_block; unsafe fn normalise_block(block_to_normalise: &mut Block) {
if let Some(next_block) = block_to_normalise.next {
while let Some(mut current) = list_ptr { let difference = next_block
if let Some(next_elem) = current.as_mut().next {
let difference = next_elem
.as_ptr() .as_ptr()
.cast::<u8>() .cast::<u8>()
.offset_from(current.as_ptr().cast::<u8>()); .offset_from((block_to_normalise as *mut Block).cast::<u8>());
let usize_difference: usize = difference if difference == block_to_normalise.size as isize {
.try_into() let next = next_block.as_ref();
.expect("distances in alloc'd blocks must be positive"); block_to_normalise.next = next.next;
block_to_normalise.size += next.size;
if usize_difference == current.as_mut().size { normalise_block(block_to_normalise);
let current = current.as_mut();
let next = next_elem.as_ref();
current.size += next.size;
current.next = next.next;
continue;
} }
} }
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) { pub unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
self.dealloc_no_normalise(ptr, layout); let point_to_normalise = self.dealloc_no_normalise(ptr, layout);
self.normalise(); 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 /// 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<SendNonNull<Block>> {
let new_layout = Block::either_layout(layout).pad_to_align(); let new_layout = Block::either_layout(layout).pad_to_align();
// note that this is a reference to a pointer // note that this is a reference to a pointer
let mut list_ptr = &mut self.state.first_free_block; let mut list_ptr = &mut self.state.first_free_block;
let mut list_ptr_prev: *mut Option<SendNonNull<Block>> = list_ptr;
// This searches the free list until it finds a block further along // 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 // 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); *list_ptr = NonNull::new(ptr.cast()).map(SendNonNull);
break; break;
} }
list_ptr_prev = list_ptr;
list_ptr = &mut current_block.as_mut().next; list_ptr = &mut current_block.as_mut().next;
} }
None => { None => {
@ -341,6 +345,8 @@ impl BlockAllocatorInner {
} }
} }
} }
list_ptr_prev
} }
} }