1 //! 当前slab分配器暂时不使用,等待后续完善后合并主线 2 #![allow(dead_code)] 3 4 use core::alloc::Layout; 5 6 // 定义Slab,用来存放空闲块 7 pub struct Slab { 8 block_size: usize, 9 free_block_list: FreeBlockList, 10 } 11 12 impl Slab { 13 /// @brief: 初始化一个slab 14 /// @param {usize} start_addr 15 /// @param {usize} slab_size 16 /// @param {usize} block_size new(start_addr: usize, slab_size: usize, block_size: usize) -> Slab17 pub unsafe fn new(start_addr: usize, slab_size: usize, block_size: usize) -> Slab { 18 let blocks_num = slab_size / block_size; 19 return Slab { 20 block_size: block_size, 21 free_block_list: FreeBlockList::new(start_addr, block_size, blocks_num), 22 }; 23 } 24 25 /// @brief: 获取slab中可用的block数 used_blocks(&self) -> usize26 pub fn used_blocks(&self) -> usize { 27 return self.free_block_list.len(); 28 } 29 30 /// @brief: 扩大free_block_list 31 /// @param {*} mut 32 /// @param {usize} start_addr 33 /// @param {usize} slab_size grow(&mut self, start_addr: usize, slab_size: usize)34 pub fn grow(&mut self, start_addr: usize, slab_size: usize) { 35 let num_of_blocks = slab_size / self.block_size; 36 let mut block_list = 37 unsafe { FreeBlockList::new(start_addr, self.block_size, num_of_blocks) }; 38 // 将新链表接到原链表的后面 39 while let Some(block) = block_list.pop() { 40 self.free_block_list.push(block); 41 } 42 } 43 /// @brief: 从slab中分配一个block 44 /// @return 分配的内存地址 allocate(&mut self, _layout: Layout) -> Option<*mut u8>45 pub fn allocate(&mut self, _layout: Layout) -> Option<*mut u8> { 46 match self.free_block_list.pop() { 47 Some(block) => return Some(block.addr() as *mut u8), 48 None => return None, 49 } 50 } 51 /// @brief: 将block归还给slab free(&mut self, ptr: *mut u8)52 pub fn free(&mut self, ptr: *mut u8) { 53 let ptr = ptr as *mut FreeBlock; 54 unsafe { 55 self.free_block_list.push(&mut *ptr); 56 } 57 } 58 } 59 /// slab中的空闲块 60 struct FreeBlockList { 61 len: usize, 62 head: Option<&'static mut FreeBlock>, 63 } 64 65 impl FreeBlockList { new(start_addr: usize, block_size: usize, num_of_blocks: usize) -> FreeBlockList66 unsafe fn new(start_addr: usize, block_size: usize, num_of_blocks: usize) -> FreeBlockList { 67 let mut new_list = FreeBlockList::new_empty(); 68 for i in (0..num_of_blocks).rev() { 69 // 从后往前分配,避免内存碎片 70 let new_block = (start_addr + i * block_size) as *mut FreeBlock; 71 new_list.push(&mut *new_block); 72 } 73 return new_list; 74 } 75 new_empty() -> FreeBlockList76 fn new_empty() -> FreeBlockList { 77 return FreeBlockList { len: 0, head: None }; 78 } 79 len(&self) -> usize80 fn len(&self) -> usize { 81 return self.len; 82 } 83 84 /// @brief: 将空闲块从链表中弹出 pop(&mut self) -> Option<&'static mut FreeBlock>85 fn pop(&mut self) -> Option<&'static mut FreeBlock> { 86 // 从链表中弹出一个空闲块 87 let block = self.head.take().map(|node| { 88 self.head = node.next.take(); 89 self.len -= 1; 90 node 91 }); 92 return block; 93 } 94 95 /// @brief: 将空闲块压入链表 push(&mut self, free_block: &'static mut FreeBlock)96 fn push(&mut self, free_block: &'static mut FreeBlock) { 97 free_block.next = self.head.take(); 98 self.len += 1; 99 self.head = Some(free_block); 100 } 101 is_empty(&self) -> bool102 fn is_empty(&self) -> bool { 103 return self.head.is_none(); 104 } 105 } 106 107 impl Drop for FreeBlockList { drop(&mut self)108 fn drop(&mut self) { 109 while let Some(_) = self.pop() {} 110 } 111 } 112 113 struct FreeBlock { 114 next: Option<&'static mut FreeBlock>, 115 } 116 117 impl FreeBlock { 118 /// @brief: 获取FreeBlock的地址 119 /// @return {*} addr(&self) -> usize120 fn addr(&self) -> usize { 121 return self as *const _ as usize; 122 } 123 } 124