diff --git a/kernel/src/vm/mod.rs b/kernel/src/vm/mod.rs index ec7b1d2eb..48f274dfa 100644 --- a/kernel/src/vm/mod.rs +++ b/kernel/src/vm/mod.rs @@ -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 { type_from_layout(layout) } diff --git a/osdk/deps/heap-allocator/src/allocator.rs b/osdk/deps/heap-allocator/src/allocator.rs index 377afaae6..6ea044824 100644 --- a/osdk/deps/heap-allocator/src/allocator.rs +++ b/osdk/deps/heap-allocator/src/allocator.rs @@ -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 { if let Some(class) = CommonSizeClass::from_layout(layout) { return Some(SlotInfo::SlabSlot(class as usize)); diff --git a/osdk/src/base_crate/main.rs.template b/osdk/src/base_crate/main.rs.template index 73f68a4bd..7d360ed09 100644 --- a/osdk/src/base_crate/main.rs.template +++ b/osdk/src/base_crate/main.rs.template @@ -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 { + fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: core::alloc::Layout) -> Option { type_from_layout(layout) } } diff --git a/ostd/libs/ostd-macros/src/lib.rs b/ostd/libs/ostd-macros/src/lib.rs index 4758f31be..26fd3755e 100644 --- a/ostd/libs/ostd-macros/src/lib.rs +++ b/ostd/libs/ostd-macros/src/lib.rs @@ -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 { ... }` to - // `const extern "Rust" fn __GLOBAL_HEAP_SLOT_SIZE_FROM_LAYOUT(layout: Layout) -> Option { ... }`. + // `const extern "Rust" fn __GLOBAL_HEAP_SLOT_INFO_FROM_LAYOUT(layout: Layout) -> Option { ... }`. // 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() diff --git a/ostd/src/lib.rs b/ostd/src/lib.rs index e0c879efd..ce1e1b20a 100644 --- a/ostd/src/lib.rs +++ b/ostd/src/lib.rs @@ -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; diff --git a/ostd/src/mm/heap/mod.rs b/ostd/src/mm/heap/mod.rs index 55fa6b39a..6718f67f3 100644 --- a/ostd/src/mm/heap/mod.rs +++ b/ostd/src/mm/heap/mod.rs @@ -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; /// 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; + /// 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; } /// 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 { // 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 { diff --git a/ostd/src/mm/heap/slab.rs b/ostd/src/mm/heap/slab.rs index 1d3155e72..29a708c17 100644 --- a/ostd/src/mm/heap/slab.rs +++ b/ostd/src/mm/heap/slab.rs @@ -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 = UniqueFrame>>; -/// 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 = Frame>>; - /// Frame metadata of a slab. /// /// Each slab is backed by a [`UniqueFrame`].