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