Skip to content

Commit e1666c7

Browse files
committed
doc: add documents of some modules
1 parent 7aed483 commit e1666c7

File tree

3 files changed

+81
-3
lines changed

3 files changed

+81
-3
lines changed

Cargo.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ name = "axalloc"
33
version = "0.1.0"
44
edition = "2021"
55
authors = ["Yuekai Jia <[email protected]>"]
6-
7-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
6+
description = "ArceOS global memory allocator"
7+
license = "GPL-3.0-or-later OR Apache-2.0"
8+
homepage = "https://github.com/rcore-os/arceos"
9+
repository = "https://github.com/rcore-os/arceos/tree/main/modules/axalloc"
10+
documentation = "https://rcore-os.github.io/arceos/axalloc/index.html"
811

912
[dependencies]
1013
log = "0.4"

src/lib.rs

+73
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//! [ArceOS](https://github.com/rcore-os/arceos) global memory allocator.
2+
//!
3+
//! It provides [`GlobalAllocator`], which implements the trait
4+
//! [`core::alloc::GlobalAlloc`]. A static global variable of type
5+
//! [`GlobalAllocator`] is defined with the `#[global_allocator]` attribute, to
6+
//! be registered as the standard library’s default allocator.
7+
18
#![no_std]
29
#![feature(alloc_error_handler)]
310

@@ -17,19 +24,34 @@ const MIN_HEAP_SIZE: usize = 0x8000; // 32 K
1724

1825
pub use page::GlobalPage;
1926

27+
/// The global allocator used by ArceOS.
28+
///
29+
/// It combines a [`ByteAllocator`] and a [`PageAllocator`] into a simple
30+
/// two-level allocator: firstly tries allocate from the byte allocator, if
31+
/// there is no memory, asks the page allocator for more memory and adds it to
32+
/// the byte allocator.
33+
///
34+
/// Currently, [`SlabByteAllocator`] is used as the byte allocator, while
35+
/// [`BitmapPageAllocator`] is used as the page allocator.
2036
pub struct GlobalAllocator {
2137
balloc: SpinNoIrq<SlabByteAllocator>,
2238
palloc: SpinNoIrq<BitmapPageAllocator<PAGE_SIZE>>,
2339
}
2440

2541
impl GlobalAllocator {
42+
/// Creates an empty [`GlobalAllocator`].
2643
pub const fn new() -> Self {
2744
Self {
2845
balloc: SpinNoIrq::new(SlabByteAllocator::new()),
2946
palloc: SpinNoIrq::new(BitmapPageAllocator::new()),
3047
}
3148
}
3249

50+
/// Initializes the allocator with the given region.
51+
///
52+
/// It firstly adds the whole region to the page allocator, then allocates
53+
/// a small region (32 KB) to initialize the byte allocator. Therefore,
54+
/// the given region must be larger than 32 KB.
3355
pub fn init(&self, start_vaddr: usize, size: usize) {
3456
assert!(size > MIN_HEAP_SIZE);
3557
let init_heap_size = MIN_HEAP_SIZE;
@@ -40,10 +62,22 @@ impl GlobalAllocator {
4062
self.balloc.lock().init(heap_ptr, init_heap_size);
4163
}
4264

65+
/// Add the given region to the allocator.
66+
///
67+
/// It will add the whole region to the byte allocator.
4368
pub fn add_memory(&self, start_vaddr: usize, size: usize) -> AllocResult {
4469
self.balloc.lock().add_memory(start_vaddr, size)
4570
}
4671

72+
/// Allocate arbitrary number of bytes. Returns the left bound of the
73+
/// allocated region.
74+
///
75+
/// It firstly tries to allocate from the byte allocator. If there is no
76+
/// memory, it asks the page allocator for more memory and adds it to the
77+
/// byte allocator.
78+
///
79+
/// `align_pow2` must be a power of 2, and the returned region bound will be
80+
/// aligned to it.
4781
pub fn alloc(&self, size: usize, align_pow2: usize) -> AllocResult<usize> {
4882
// simple two-level allocator: if no heap memory, allocate from the page allocator.
4983
let mut balloc = self.balloc.lock();
@@ -64,30 +98,54 @@ impl GlobalAllocator {
6498
}
6599
}
66100

101+
/// Gives back the allocated region to the byte allocator.
102+
///
103+
/// The region should be allocated by [`alloc`], and `align_pow2` should be
104+
/// the same as the one used in [`alloc`]. Otherwise, the behavior is
105+
/// undefined.
106+
///
107+
/// [`alloc`]: GlobalAllocator::alloc
67108
pub fn dealloc(&self, pos: usize, size: usize, align_pow2: usize) {
68109
self.balloc.lock().dealloc(pos, size, align_pow2)
69110
}
70111

112+
/// Allocates contiguous pages.
113+
///
114+
/// It allocates `num_pages` pages from the page allocator.
115+
///
116+
/// `align_pow2` must be a power of 2, and the returned region bound will be
117+
/// aligned to it.
71118
pub fn alloc_pages(&self, num_pages: usize, align_pow2: usize) -> AllocResult<usize> {
72119
self.palloc.lock().alloc_pages(num_pages, align_pow2)
73120
}
74121

122+
/// Gives back the allocated pages starts from `pos` to the page allocator.
123+
///
124+
/// The pages should be allocated by [`alloc_pages`], and `align_pow2`
125+
/// should be the same as the one used in [`alloc_pages`]. Otherwise, the
126+
/// behavior is undefined.
127+
///
128+
/// [`alloc_pages`]: GlobalAllocator::alloc_pages
75129
pub fn dealloc_pages(&self, pos: usize, num_pages: usize) {
76130
self.palloc.lock().dealloc_pages(pos, num_pages)
77131
}
78132

133+
/// Returns the number of allocated bytes in the byte allocator.
79134
pub fn used_bytes(&self) -> usize {
80135
self.balloc.lock().used_bytes()
81136
}
82137

138+
/// Returns the number of available bytes in the byte allocator.
83139
pub fn available_bytes(&self) -> usize {
84140
self.balloc.lock().available_bytes()
85141
}
86142

143+
/// Returns the number of allocated pages in the page allocator.
87144
pub fn used_pages(&self) -> usize {
88145
self.palloc.lock().used_pages()
89146
}
90147

148+
/// Returns the number of available pages in the page allocator.
91149
pub fn available_pages(&self) -> usize {
92150
self.palloc.lock().available_pages()
93151
}
@@ -120,10 +178,19 @@ fn handle_alloc_error(layout: Layout) -> ! {
120178
);
121179
}
122180

181+
/// Returns the reference to the global allocator.
123182
pub fn global_allocator() -> &'static GlobalAllocator {
124183
&GLOBAL_ALLOCATOR
125184
}
126185

186+
/// Initializes the global allocator with the given memory region.
187+
///
188+
/// Note that the memory region bounds are just numbers, and the allocator
189+
/// does not actually access the region. Users should ensure that the region
190+
/// is valid and not being used by others, so that the allocated memory is also
191+
/// valid.
192+
///
193+
/// This function should be called only once, and before any allocation.
127194
pub fn global_init(start_vaddr: usize, size: usize) {
128195
debug!(
129196
"initialize global allocator at: [{:#x}, {:#x})",
@@ -133,6 +200,12 @@ pub fn global_init(start_vaddr: usize, size: usize) {
133200
GLOBAL_ALLOCATOR.init(start_vaddr, size);
134201
}
135202

203+
/// Add the given memory region to the global allocator.
204+
///
205+
/// Users should ensure that the region is valid and not being used by others,
206+
/// so that the allocated memory is also valid.
207+
///
208+
/// It's similar to [`global_init`], but can be called multiple times.
136209
pub fn global_add_memory(start_vaddr: usize, size: usize) -> AllocResult {
137210
debug!(
138211
"add a memory region to global allocator: [{:#x}, {:#x})",

src/page.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use memory_addr::{PhysAddr, VirtAddr};
44

55
use crate::{global_allocator, PAGE_SIZE};
66

7-
/// A safe wrapper of contiguous 4K-sized pages.
7+
/// A RAII wrapper of contiguous 4K-sized pages.
8+
///
9+
/// It will automatically deallocate the pages when dropped.
810
#[derive(Debug)]
911
pub struct GlobalPage {
1012
start_vaddr: VirtAddr,

0 commit comments

Comments
 (0)