mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-15 08:16:47 +00:00
Revise the docs of the slab and remove an unused type
This commit is contained in:
parent
3d21258baf
commit
288942b970
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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`].
|
||||||
|
Loading…
x
Reference in New Issue
Block a user