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]
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> {
type_from_layout(layout)
}

View File

@ -85,7 +85,7 @@ impl CommonSizeClass {
/// 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> {
if let Some(class) = CommonSizeClass::from_layout(layout) {
return Some(SlotInfo::SlabSlot(class as usize));

View File

@ -37,7 +37,7 @@ mod default_heap_allocator {
#[no_mangle]
#[linkage = "weak"]
#[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)
}
}

View File

@ -148,19 +148,25 @@ pub fn global_heap_allocator(_attr: TokenStream, item: TokenStream) -> TokenStre
.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
/// allocation with the layout. The function should return `None` if the layout
/// is not supported.
/// In OSTD, both slab slots and large slots are used to serve heap allocations.
/// Slab slots must come from slabs of fixed sizes, while large slots can be
/// 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
/// to be `const`.
#[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
// `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`.
let item = parse_macro_input!(item as syn::ItemFn);
assert!(
@ -169,7 +175,7 @@ pub fn global_heap_allocator_slot_type_map(_attr: TokenStream, item: TokenStream
);
quote!(
#[export_name = "__GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT"]
#[export_name = "__GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT"]
#item
)
.into()

View File

@ -48,7 +48,7 @@ mod util;
use core::sync::atomic::{AtomicBool, Ordering};
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,
};
pub use ostd_pod::Pod;

View File

@ -14,7 +14,7 @@ mod slot;
mod slot_list;
pub use self::{
slab::{SharedSlab, Slab, SlabMeta},
slab::{Slab, SlabMeta},
slot::{HeapSlot, SlotInfo},
slot_list::SlabSlotList,
};
@ -27,7 +27,7 @@ pub use self::{
///
/// To provide the global heap allocator, use [`crate::global_heap_allocator`]
/// 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
/// future.
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
/// least the alignment of the layout. Furthermore, the size of the
/// 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>;
/// Deallocates a [`HeapSlot`].
@ -56,9 +56,9 @@ extern "Rust" {
/// [`crate::global_heap_allocator`] attribute.
static __GLOBAL_HEAP_ALLOCATOR_REF: &'static dyn GlobalHeapAllocator;
/// Gets the size and type of the heap slot to serve an allocation.
/// See [`crate::global_heap_allocator_slot_type_map`].
fn __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo>;
/// Gets the size and type of heap slots to serve allocations of the layout.
/// See [`crate::global_heap_allocator_slot_map`].
fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: Layout) -> Option<SlotInfo>;
}
/// 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 }
}
/// 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,
/// as we require it to be implemented as a `const fn`.
/// This function is defined by the OSTD user and should be idempotent, as we
/// 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> {
// 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 {

View File

@ -7,29 +7,22 @@ use core::{alloc::AllocError, ptr::NonNull};
use super::{slot::HeapSlot, slot_list::SlabSlotList};
use crate::mm::{
frame::{linked_list::Link, meta::AnyFrameMeta},
paddr_to_vaddr, Frame, FrameAllocOptions, UniqueFrame, PAGE_SIZE,
paddr_to_vaddr, FrameAllocOptions, UniqueFrame, PAGE_SIZE,
};
/// A slab.
///
/// The slot size is the maximum size and alignment of the objects that can be
/// allocated from the slab. The slab is divided into slots of this size.
/// The slot size is the maximum size of objects that can be allocated from the
/// 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
/// be a power of two. The size of the slab should be larger than the slot
/// size and [`PAGE_SIZE`].
/// The `SLOT_SIZE` is the size of the slots in bytes. The size of the slots
/// cannot be smaller than the size of [`usize`]. It must be smaller than or
/// equal to [`PAGE_SIZE`].
///
/// The `SLOT_SIZE` is the size of the slot in bytes. It must be smaller than or
/// equal to [`PAGE_SIZE`]. This restriction may be lifted in the future.
/// A slab should have the size of one basic page. This restriction may be
/// lifted in the future.
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.
///
/// Each slab is backed by a [`UniqueFrame`].