obkrnl/uma/slab.rs
1use super::{UmaFlags, UmaKeg};
2
3/// Implementation of `uma_slab` and `uma_slab_refcnt`.
4///
5/// We use slightly different mechanism here but has the same memory layout.
6///
7/// # Safety
8/// Adding more fields into this struct without knowing how it work can cause undefined behavior in
9/// some places.
10#[repr(C)]
11pub struct Slab<I> {
12 pub hdr: SlabHdr, // us_head
13 pub free: [I], // us_freelist
14}
15
16impl<I> Slab<I> {
17 /// See `slab_alloc_item` on the Orbis for a reference.
18 ///
19 /// # Safety
20 /// This slab must be allocated from `keg`.
21 ///
22 /// # Reference offsets
23 /// | Version | Offset |
24 /// |---------|--------|
25 /// |PS4 11.00|0x141FE0|
26 pub unsafe fn alloc_item(&mut self, keg: &UmaKeg<I>) -> *mut u8 {
27 self.hdr.free_count -= 1;
28
29 if self.hdr.free_count != 0 {
30 let off = self.hdr.first_free * keg.allocated_size();
31
32 return unsafe { self.hdr.items.add(off) };
33 }
34
35 todo!()
36 }
37}
38
39/// Implementation of `uma_slab_head`.
40pub struct SlabHdr {
41 pub free_count: usize, // us_freecount
42 pub first_free: usize, // us_firstfree
43 pub items: *mut u8, // us_data
44}
45
46/// Item in [Slab::free] to represents `uma_slab` structure.
47#[repr(C)]
48pub struct StdFree {
49 pub item: u8, // us_item
50}
51
52unsafe impl FreeItem for StdFree {
53 fn new(idx: usize) -> Self {
54 Self {
55 item: (idx + 1).try_into().unwrap(),
56 }
57 }
58
59 fn flags() -> UmaFlags {
60 UmaFlags::zeroed()
61 }
62}
63
64/// Item in [Slab::free] to represents `uma_slab_refcnt` structure.
65#[repr(C)]
66#[allow(dead_code)] // TODO: Remove this.
67pub struct RefFree {
68 pub item: u8, // us_item
69 pub refs: u32, // us_refcnt
70}
71
72unsafe impl FreeItem for RefFree {
73 fn new(idx: usize) -> Self {
74 Self {
75 item: (idx + 1).try_into().unwrap(),
76 refs: 0,
77 }
78 }
79
80 fn flags() -> UmaFlags {
81 UmaFlags::VToSlab.into()
82 }
83}
84
85/// Each item in [Slab::free].
86///
87/// # Safety
88/// Wrong flags from [Self::flags()] can cause undefined behavior in some places.
89pub unsafe trait FreeItem: Sized {
90 fn new(idx: usize) -> Self;
91 fn flags() -> UmaFlags;
92}