Revise the docs of the slab and remove an unused type

This commit is contained in:
Zhang Junyang 2025-03-14 20:57:06 +08:00 committed by Tate, Hongliang Tian
parent 3d21258baf
commit 288942b970
7 changed files with 37 additions and 38 deletions

View File

@ -31,7 +31,7 @@ static FRAME_ALLOCATOR: FrameAllocator = FrameAllocator;
#[ostd::global_heap_allocator] #[ostd::global_heap_allocator]
static HEAP_ALLOCATOR: HeapAllocator = HeapAllocator; static HEAP_ALLOCATOR: HeapAllocator = HeapAllocator;
#[ostd::global_heap_allocator_slot_type_map] #[ostd::global_heap_allocator_slot_map]
const fn slot_type_from_layout(layout: core::alloc::Layout) -> Option<ostd::mm::heap::SlotInfo> { const fn slot_type_from_layout(layout: core::alloc::Layout) -> Option<ostd::mm::heap::SlotInfo> {
type_from_layout(layout) type_from_layout(layout)
} }

View File

@ -85,7 +85,7 @@ impl CommonSizeClass {
/// Get the type of the slot from the layout. /// Get the type of the slot from the layout.
/// ///
/// It should be used to define [`ostd::global_heap_allocator_slot_type_map`]. /// It should be used to define [`ostd::global_heap_allocator_slot_map`].
pub const fn type_from_layout(layout: Layout) -> Option<SlotInfo> { pub const fn type_from_layout(layout: Layout) -> Option<SlotInfo> {
if let Some(class) = CommonSizeClass::from_layout(layout) { if let Some(class) = CommonSizeClass::from_layout(layout) {
return Some(SlotInfo::SlabSlot(class as usize)); return Some(SlotInfo::SlabSlot(class as usize));

View File

@ -37,7 +37,7 @@ mod default_heap_allocator {
#[no_mangle] #[no_mangle]
#[linkage = "weak"] #[linkage = "weak"]
#[expect(non_snake_case)] #[expect(non_snake_case)]
fn __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout: core::alloc::Layout) -> Option<ostd::mm::heap::SlotInfo> { fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: core::alloc::Layout) -> Option<ostd::mm::heap::SlotInfo> {
type_from_layout(layout) type_from_layout(layout)
} }
} }

View File

@ -148,19 +148,25 @@ pub fn global_heap_allocator(_attr: TokenStream, item: TokenStream) -> TokenStre
.into() .into()
} }
/// A macro attribute to provide the heap slot type given the layout. /// A macro attribute to map allocation layouts to slot sizes and types.
/// ///
/// The users must decide the size and the type of the heap slot to serve an /// In OSTD, both slab slots and large slots are used to serve heap allocations.
/// allocation with the layout. The function should return `None` if the layout /// Slab slots must come from slabs of fixed sizes, while large slots can be
/// is not supported. /// allocated by frame allocation, with sizes being multiples of pages.
/// OSTD must know the user's decision on the size and type of a slot to serve
/// an allocation with a given layout.
/// ///
/// The annotated function should be idempotent, i.e., the result should be the /// This macro should be used to annotate a function that maps a layout to the
/// slot size and the type. The function should return `None` if the layout is
/// not supported.
///
/// The annotated function should be idempotent, meaning the result should be the
/// same for the same layout. OSDK enforces this by only allowing the function /// same for the same layout. OSDK enforces this by only allowing the function
/// to be `const`. /// to be `const`.
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn global_heap_allocator_slot_type_map(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn global_heap_allocator_slot_map(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Rewrite the input `const fn __any_name__(layout: Layout) -> Option<SlotInfo> { ... }` to // Rewrite the input `const fn __any_name__(layout: Layout) -> Option<SlotInfo> { ... }` to
// `const extern "Rust" fn __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo> { ... }`. // `const extern "Rust" fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo> { ... }`.
// Reject if the input is not a `const fn`. // Reject if the input is not a `const fn`.
let item = parse_macro_input!(item as syn::ItemFn); let item = parse_macro_input!(item as syn::ItemFn);
assert!( assert!(
@ -169,7 +175,7 @@ pub fn global_heap_allocator_slot_type_map(_attr: TokenStream, item: TokenStream
); );
quote!( quote!(
#[export_name = "__GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT"] #[export_name = "__GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT"]
#item #item
) )
.into() .into()

View File

@ -48,7 +48,7 @@ mod util;
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
pub use ostd_macros::{ pub use ostd_macros::{
global_frame_allocator, global_heap_allocator, global_heap_allocator_slot_type_map, main, global_frame_allocator, global_heap_allocator, global_heap_allocator_slot_map, main,
panic_handler, panic_handler,
}; };
pub use ostd_pod::Pod; pub use ostd_pod::Pod;

View File

@ -14,7 +14,7 @@ mod slot;
mod slot_list; mod slot_list;
pub use self::{ pub use self::{
slab::{SharedSlab, Slab, SlabMeta}, slab::{Slab, SlabMeta},
slot::{HeapSlot, SlotInfo}, slot::{HeapSlot, SlotInfo},
slot_list::SlabSlotList, slot_list::SlabSlotList,
}; };
@ -27,7 +27,7 @@ pub use self::{
/// ///
/// To provide the global heap allocator, use [`crate::global_heap_allocator`] /// To provide the global heap allocator, use [`crate::global_heap_allocator`]
/// to mark a static variable that implements this trait. Use /// to mark a static variable that implements this trait. Use
/// [`crate::global_heap_allocator_slot_type_map`] to specify the sizes of /// [`crate::global_heap_allocator_slot_map`] to specify the sizes of
/// slots for different layouts. This latter restriction may be lifted in the /// slots for different layouts. This latter restriction may be lifted in the
/// future. /// future.
pub trait GlobalHeapAllocator: Sync { pub trait GlobalHeapAllocator: Sync {
@ -39,7 +39,7 @@ pub trait GlobalHeapAllocator: Sync {
/// must be at least the size of the layout and the alignment must be at /// must be at least the size of the layout and the alignment must be at
/// least the alignment of the layout. Furthermore, the size of the /// least the alignment of the layout. Furthermore, the size of the
/// returned [`HeapSlot`] must match the size returned by the function /// returned [`HeapSlot`] must match the size returned by the function
/// marked with [`crate::global_heap_allocator_slot_type_map`]. /// marked with [`crate::global_heap_allocator_slot_map`].
fn alloc(&self, layout: Layout) -> Result<HeapSlot, AllocError>; fn alloc(&self, layout: Layout) -> Result<HeapSlot, AllocError>;
/// Deallocates a [`HeapSlot`]. /// Deallocates a [`HeapSlot`].
@ -56,9 +56,9 @@ extern "Rust" {
/// [`crate::global_heap_allocator`] attribute. /// [`crate::global_heap_allocator`] attribute.
static __GLOBAL_HEAP_ALLOCATOR_REF: &'static dyn GlobalHeapAllocator; static __GLOBAL_HEAP_ALLOCATOR_REF: &'static dyn GlobalHeapAllocator;
/// Gets the size and type of the heap slot to serve an allocation. /// Gets the size and type of heap slots to serve allocations of the layout.
/// See [`crate::global_heap_allocator_slot_type_map`]. /// See [`crate::global_heap_allocator_slot_map`].
fn __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo>; fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo>;
} }
/// Gets the reference to the user-defined global heap allocator. /// Gets the reference to the user-defined global heap allocator.
@ -67,15 +67,15 @@ fn get_global_heap_allocator() -> &'static dyn GlobalHeapAllocator {
unsafe { __GLOBAL_HEAP_ALLOCATOR_REF } unsafe { __GLOBAL_HEAP_ALLOCATOR_REF }
} }
/// Gets the size and type of the heap slot to serve an allocation. /// Gets the size and type of heap slots to serve allocations of the layout.
/// ///
/// This function is defined by the OSTD user and should be idempotent, /// This function is defined by the OSTD user and should be idempotent, as we
/// as we require it to be implemented as a `const fn`. /// require it to be implemented as a `const fn`.
/// ///
/// See [`crate::global_heap_allocator_slot_type_map`]. /// See [`crate::global_heap_allocator_slot_map`].
fn slot_size_from_layout(layout: Layout) -> Option<SlotInfo> { fn slot_size_from_layout(layout: Layout) -> Option<SlotInfo> {
// SAFETY: This up-call is redirected safely to Rust code by OSDK. // SAFETY: This up-call is redirected safely to Rust code by OSDK.
unsafe { __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout) } unsafe { __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout) }
} }
macro_rules! abort_with_message { macro_rules! abort_with_message {

View File

@ -7,29 +7,22 @@ use core::{alloc::AllocError, ptr::NonNull};
use super::{slot::HeapSlot, slot_list::SlabSlotList}; use super::{slot::HeapSlot, slot_list::SlabSlotList};
use crate::mm::{ use crate::mm::{
frame::{linked_list::Link, meta::AnyFrameMeta}, frame::{linked_list::Link, meta::AnyFrameMeta},
paddr_to_vaddr, Frame, FrameAllocOptions, UniqueFrame, PAGE_SIZE, paddr_to_vaddr, FrameAllocOptions, UniqueFrame, PAGE_SIZE,
}; };
/// A slab. /// A slab.
/// ///
/// The slot size is the maximum size and alignment of the objects that can be /// The slot size is the maximum size of objects that can be allocated from the
/// allocated from the slab. The slab is divided into slots of this size. /// slab. The slab is densely divided into slots of this size.
/// ///
/// The size of the slot cannot be smaller than the size of [`usize`] and must /// The `SLOT_SIZE` is the size of the slots in bytes. The size of the slots
/// be a power of two. The size of the slab should be larger than the slot /// cannot be smaller than the size of [`usize`]. It must be smaller than or
/// size and [`PAGE_SIZE`]. /// equal to [`PAGE_SIZE`].
/// ///
/// The `SLOT_SIZE` is the size of the slot in bytes. It must be smaller than or /// A slab should have the size of one basic page. This restriction may be
/// equal to [`PAGE_SIZE`]. This restriction may be lifted in the future. /// lifted in the future.
pub type Slab<const SLOT_SIZE: usize> = UniqueFrame<Link<SlabMeta<SLOT_SIZE>>>; pub type Slab<const SLOT_SIZE: usize> = UniqueFrame<Link<SlabMeta<SLOT_SIZE>>>;
/// A shared pointer to a slab.
///
/// It is solely useful to point to a slab from a stray slot. When an object of
/// this type exists no mutable references can be created to the slab. So don't
/// hold it for long.
pub type SharedSlab<const SLOT_SIZE: usize> = Frame<Link<SlabMeta<SLOT_SIZE>>>;
/// Frame metadata of a slab. /// Frame metadata of a slab.
/// ///
/// Each slab is backed by a [`UniqueFrame`]. /// Each slab is backed by a [`UniqueFrame`].