1#![feature(allocator_api)]
2#![feature(nonnull_slice_from_raw_parts)]
3#![feature(alloc_layout_extra)]
4#![allow(irrefutable_let_patterns)]
5#![no_std]
6#![allow(unused)]
7
8#[macro_use]
9extern crate log;
10extern crate alloc;
11mod formation;
12mod kmalloc;
13mod slab;
14
15use crate::formation::SlabError;
16use crate::slab::{create_mem_cache, MemCache, SlabInfo};
17use core::marker::PhantomData;
18use doubly_linked_list::*;
19use preprint::pprintln;
20
21pub use crate::slab::{print_slab_system_info};
22pub use kmalloc::SlabAllocator;
23
24static mut SLAB_CACHES: ListHead = ListHead::new();
26static mut MEM_CACHE_BOOT: MemCache = MemCache::new();
27
28static mut FRAME_SIZE: usize = 0x1000;
30static mut CACHE_LINE_SIZE: usize = 16;
32
33#[inline]
34fn frame_size() -> usize {
35 unsafe { FRAME_SIZE }
36}
37
38#[inline]
39fn cls() -> usize {
40 unsafe { CACHE_LINE_SIZE }
41}
42
43extern "C" {
44 fn alloc_frames(num: usize) -> *mut u8;
46 fn free_frames(addr: *mut u8, num: usize);
48 fn current_cpu_id() -> usize;
50}
51
52pub fn init_slab_system(frame_size: usize, cache_line_size: usize) {
54 init_slab_info(frame_size, cache_line_size);
55 slab::mem_cache_init();
57 kmalloc::init_kmalloc();
59}
60
61#[inline]
63fn init_slab_info(frame_size: usize, cache_line_size: usize) {
64 unsafe {
65 FRAME_SIZE = frame_size;
66 CACHE_LINE_SIZE = cache_line_size;
67 }
68}
69
70pub trait Object {
74 fn construct() -> Self;
75}
76
77pub trait ObjectAllocator<T: Object> {
79 fn alloc(&self) -> Result<&mut T,SlabError>;
81 fn dealloc(&self, obj: &mut T) -> Result<(), SlabError>;
83 fn destroy(&mut self);
85}
86
87pub struct SlabCache<T: Object> {
88 cache: &'static mut MemCache,
89 obj_type: PhantomData<T>,
90}
91
92impl<T: Object> SlabCache<T> {
93 pub fn new(name: &'static str) -> Result<SlabCache<T>, SlabError> {
94 let size = core::mem::size_of::<T>() as u32;
95 let align = core::mem::align_of::<T>() as u32;
96 let cache = create_mem_cache(name, size, align)?;
97 Ok(SlabCache {
98 cache,
99 obj_type: PhantomData,
100 })
101 }
102 pub fn print_info(&self) {
103 self.cache.print_info();
104 }
105 pub fn get_cache_info(&self)->SlabInfo{
106 self.cache.get_cache_info()
107 }
108}
109
110impl<T: Object> ObjectAllocator<T> for SlabCache<T> {
111 fn alloc(&self) -> Result<&mut T,SlabError> {
112 let obj_ptr = self.cache.alloc()?;
113 unsafe {
114 let obj = obj_ptr as *mut T;
115 obj.write(T::construct());
116 Ok(&mut *obj)
117 }
118 }
119 fn dealloc(&self, obj: &mut T) -> Result<(), SlabError> {
120 self.cache.dealloc(obj as *mut T as *mut u8)
121 }
122 fn destroy(&mut self) {
123 self.cache.destroy();
124 }
125}