buddy_slab_allocator/slab/
size_class.rs1use core::alloc::Layout;
6
7pub const SIZE_CLASS_COUNT: usize = 9;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[repr(u8)]
13pub enum SizeClass {
14 Bytes8 = 0,
15 Bytes16 = 1,
16 Bytes32 = 2,
17 Bytes64 = 3,
18 Bytes128 = 4,
19 Bytes256 = 5,
20 Bytes512 = 6,
21 Bytes1024 = 7,
22 Bytes2048 = 8,
23}
24
25pub const SLAB_MAX_SIZE: usize = 2048;
27
28const CLASS_SIZES: [usize; SIZE_CLASS_COUNT] = [8, 16, 32, 64, 128, 256, 512, 1024, 2048];
30
31impl SizeClass {
32 pub const ALL: [SizeClass; SIZE_CLASS_COUNT] = [
34 SizeClass::Bytes8,
35 SizeClass::Bytes16,
36 SizeClass::Bytes32,
37 SizeClass::Bytes64,
38 SizeClass::Bytes128,
39 SizeClass::Bytes256,
40 SizeClass::Bytes512,
41 SizeClass::Bytes1024,
42 SizeClass::Bytes2048,
43 ];
44
45 pub const COUNT: usize = SIZE_CLASS_COUNT;
47
48 pub fn from_layout(layout: Layout) -> Option<SizeClass> {
52 let size = layout.size().max(layout.align());
53 if size > SLAB_MAX_SIZE {
54 return None;
55 }
56 for (i, &class_size) in CLASS_SIZES.iter().enumerate() {
57 if size <= class_size {
58 return Some(SizeClass::ALL[i]);
59 }
60 }
61 None
62 }
63
64 pub const fn size(self) -> usize {
66 CLASS_SIZES[self as usize]
67 }
68
69 pub const fn index(self) -> usize {
71 self as usize
72 }
73
74 pub const fn slab_pages(self, page_size: usize) -> usize {
79 let obj_size = self.size();
80 if obj_size <= 256 {
81 1
82 } else if obj_size <= 1024 {
83 2
84 } else {
85 let v = 16 * page_size / (obj_size * 8);
87 let v = if v < 4 { v } else { 4 };
88 if v < 1 { 1 } else { v }
89 }
90 }
91}