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