1 //! A slab allocator implementation for objects less than a page-size (4 KiB or 2MiB). 2 //! 3 //! # Overview 4 //! 5 //! The organization is as follows: 6 //! 7 //! * A `ZoneAllocator` manages many `SCAllocator` and can 8 //! satisfy requests for different allocation sizes. 9 //! * A `SCAllocator` allocates objects of exactly one size. 10 //! It stores the objects and meta-data in one or multiple `AllocablePage` objects. 11 //! * A trait `AllocablePage` that defines the page-type from which we allocate objects. 12 //! 13 //! Lastly, it provides two default `AllocablePage` implementations `ObjectPage` and `LargeObjectPage`: 14 //! * A `ObjectPage` that is 4 KiB in size and contains allocated objects and associated meta-data. 15 //! * A `LargeObjectPage` that is 2 MiB in size and contains allocated objects and associated meta-data. 16 //! 17 //! 18 //! # Implementing GlobalAlloc 19 //! See the [global alloc](https://github.com/gz/rust-slabmalloc/tree/master/examples/global_alloc.rs) example. 20 #![allow(unused_features)] 21 #![cfg_attr(feature = "unstable", feature(const_mut_refs))] 22 #![no_std] 23 #![crate_name = "slabmalloc"] 24 #![crate_type = "lib"] 25 #![feature(new_uninit)] 26 #![feature(maybe_uninit_as_bytes)] 27 28 extern crate alloc; 29 30 mod pages; 31 mod sc; 32 mod zone; 33 34 pub use pages::*; 35 pub use sc::*; 36 pub use zone::*; 37 38 use core::alloc::Layout; 39 use core::fmt; 40 use core::ptr::{self, NonNull}; 41 42 use log::trace; 43 44 /// How many bytes in the page are used by allocator meta-data. 45 const OBJECT_PAGE_METADATA_OVERHEAD: usize = 80; 46 47 /// How many bytes a [`ObjectPage`] is. 48 const OBJECT_PAGE_SIZE: usize = 4096; 49 50 type VAddr = usize; 51 52 /// Error that can be returned for `allocation` and `deallocation` requests. 53 #[derive(Debug)] 54 pub enum AllocationError { 55 /// Can't satisfy the allocation request for Layout because the allocator 56 /// does not have enough memory (you may be able to `refill` it). 57 OutOfMemory, 58 /// Allocator can't deal with the provided size of the Layout. 59 InvalidLayout, 60 } 61 62 /// Allocator trait to be implemented by users of slabmalloc to provide memory to slabmalloc. 63 /// 64 /// # Safety 65 /// Needs to adhere to safety requirements of a rust allocator (see GlobalAlloc et. al.). 66 pub unsafe trait Allocator<'a> { allocate(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocationError>67 fn allocate(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocationError>; deallocate( &mut self, ptr: NonNull<u8>, layout: Layout, slab_callback: &'static dyn CallBack, ) -> Result<(), AllocationError>68 unsafe fn deallocate( 69 &mut self, 70 ptr: NonNull<u8>, 71 layout: Layout, 72 slab_callback: &'static dyn CallBack, 73 ) -> Result<(), AllocationError>; 74 75 /// Refill the allocator with a [`ObjectPage`]. 76 /// 77 /// # Safety 78 /// TBD (this API needs to change anyways, likely new page should be a raw pointer) refill( &mut self, layout: Layout, new_page: &'a mut ObjectPage<'a>, ) -> Result<(), AllocationError>79 unsafe fn refill( 80 &mut self, 81 layout: Layout, 82 new_page: &'a mut ObjectPage<'a>, 83 ) -> Result<(), AllocationError>; 84 } 85 86 /// 将slab_page归还Buddy的回调函数 87 pub trait CallBack: Send + Sync { free_slab_page(&self, _: *mut u8, _: usize)88 unsafe fn free_slab_page(&self, _: *mut u8, _: usize) {} 89 } 90