fix: bugs
This commit is contained in:
@@ -55,8 +55,14 @@ struct ListNode {
|
||||
|
||||
const BLOCK_SIZES: &[usize] = &[8, 16, 32, 64, 128, 256, 512, 1024, 2048];
|
||||
|
||||
struct LargeBlockNode {
|
||||
size: usize,
|
||||
next: Option<&'static mut LargeBlockNode>,
|
||||
}
|
||||
|
||||
pub struct SlabAllocator {
|
||||
list_heads: [Option<&'static mut ListNode>; BLOCK_SIZES.len()],
|
||||
large_block_free: Option<&'static mut LargeBlockNode>,
|
||||
heap_start: usize,
|
||||
heap_end: usize,
|
||||
next_bump: usize,
|
||||
@@ -66,6 +72,7 @@ impl SlabAllocator {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
list_heads: [None, None, None, None, None, None, None, None, None],
|
||||
large_block_free: None,
|
||||
heap_start: 0,
|
||||
heap_end: 0,
|
||||
next_bump: 0,
|
||||
@@ -84,11 +91,28 @@ impl SlabAllocator {
|
||||
}
|
||||
|
||||
fn fallback_alloc(&mut self, layout: Layout) -> *mut u8 {
|
||||
let size = layout.size().max(layout.align());
|
||||
|
||||
if size > 2048 {
|
||||
let mut field: *mut Option<&'static mut LargeBlockNode> = &mut self.large_block_free;
|
||||
unsafe {
|
||||
while let Some(ref mut node) = *field {
|
||||
if node.size >= size {
|
||||
let node_ptr: *mut LargeBlockNode = *node;
|
||||
let next = node.next.take();
|
||||
*field = next;
|
||||
return node_ptr as *mut u8;
|
||||
}
|
||||
field = &mut node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let alloc_start = (self.next_bump + layout.align() - 1) & !(layout.align() - 1);
|
||||
let alloc_end = alloc_start.checked_add(layout.size()).unwrap_or(self.heap_end + 1);
|
||||
|
||||
if alloc_end > self.heap_end {
|
||||
null_mut() // Out of memory
|
||||
null_mut()
|
||||
} else {
|
||||
self.next_bump = alloc_end;
|
||||
alloc_start as *mut u8
|
||||
@@ -139,6 +163,17 @@ unsafe impl GlobalAlloc for Locked<SlabAllocator> {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Large block: add to free list for reuse
|
||||
let size = layout.size().max(layout.align());
|
||||
let new_node = LargeBlockNode {
|
||||
size,
|
||||
next: allocator.large_block_free.take(),
|
||||
};
|
||||
let new_node_ptr = ptr as *mut LargeBlockNode;
|
||||
unsafe {
|
||||
new_node_ptr.write(new_node);
|
||||
allocator.large_block_free = Some(&mut *new_node_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user