Skip to content

Commit acdea3d

Browse files
committed
添加初始化测试
1 parent 31155ce commit acdea3d

8 files changed

Lines changed: 881 additions & 0 deletions

File tree

allocator/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ tracking = []
1515
log = { version = "0.4", optional = true }
1616
cfg-if = "1.0"
1717

18+
[dev-dependencies]
19+
1820

allocator/src/buddy/buddy_allocator.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,87 @@ impl<const PAGE_SIZE: usize> PageAllocator for BuddyPageAllocator<PAGE_SIZE> {
544544
return 0;
545545
}
546546
}
547+
548+
#[cfg(test)]
549+
mod tests {
550+
use super::*;
551+
use alloc::alloc::{alloc, dealloc};
552+
use core::alloc::Layout;
553+
554+
const TEST_HEAP_SIZE: usize = 16 * 1024 * 1024;
555+
const TEST_PAGE_SIZE: usize = 0x1000;
556+
557+
fn alloc_test_heap(size: usize) -> (*mut u8, Layout) {
558+
let layout = Layout::from_size_align(size, TEST_PAGE_SIZE).unwrap();
559+
let ptr = unsafe { alloc(layout) };
560+
assert!(!ptr.is_null());
561+
(ptr, layout)
562+
}
563+
564+
fn dealloc_test_heap(ptr: *mut u8, layout: Layout) {
565+
unsafe { dealloc(ptr, layout) };
566+
}
567+
568+
#[test]
569+
fn test_buddy_allocator_init() {
570+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
571+
let heap_addr = heap_ptr as usize;
572+
573+
let mut allocator = BuddyPageAllocator::<TEST_PAGE_SIZE>::new();
574+
allocator.init(heap_addr, TEST_HEAP_SIZE);
575+
576+
let addr = allocator.alloc_pages(1, TEST_PAGE_SIZE);
577+
assert!(addr.is_ok());
578+
if let Ok(a) = addr {
579+
allocator.dealloc_pages(a, 1);
580+
}
581+
582+
dealloc_test_heap(heap_ptr, heap_layout);
583+
}
584+
585+
#[test]
586+
fn test_buddy_allocator_multi_pages() {
587+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
588+
let heap_addr = heap_ptr as usize;
589+
590+
let mut allocator = BuddyPageAllocator::<TEST_PAGE_SIZE>::new();
591+
allocator.init(heap_addr, TEST_HEAP_SIZE);
592+
593+
let addr1 = allocator.alloc_pages(4, TEST_PAGE_SIZE).unwrap();
594+
let addr2 = allocator.alloc_pages(8, TEST_PAGE_SIZE).unwrap();
595+
assert_ne!(addr1, addr2);
596+
597+
allocator.dealloc_pages(addr1, 4);
598+
allocator.dealloc_pages(addr2, 8);
599+
600+
dealloc_test_heap(heap_ptr, heap_layout);
601+
}
602+
603+
#[test]
604+
fn test_buddy_allocator_alignment() {
605+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
606+
let heap_addr = heap_ptr as usize;
607+
608+
let mut allocator = BuddyPageAllocator::<TEST_PAGE_SIZE>::new();
609+
allocator.init(heap_addr, TEST_HEAP_SIZE);
610+
611+
let addr = allocator.alloc_pages(1, TEST_PAGE_SIZE * 4).unwrap();
612+
assert_eq!(addr & (TEST_PAGE_SIZE * 4 - 1), 0);
613+
614+
allocator.dealloc_pages(addr, 1);
615+
dealloc_test_heap(heap_ptr, heap_layout);
616+
}
617+
618+
#[test]
619+
fn test_buddy_allocator_zone_count() {
620+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
621+
let heap_addr = heap_ptr as usize;
622+
623+
let mut allocator = BuddyPageAllocator::<TEST_PAGE_SIZE>::new();
624+
allocator.init(heap_addr, TEST_HEAP_SIZE);
625+
626+
assert_eq!(allocator.get_zone_count(), 1);
627+
628+
dealloc_test_heap(heap_ptr, heap_layout);
629+
}
630+
}

allocator/src/global_allocator.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,16 @@ impl<const PAGE_SIZE: usize> GlobalAllocator<PAGE_SIZE> {
187187
}
188188

189189
/// Initialize allocator with given memory region
190+
///
191+
/// # Examples
192+
///
193+
/// ```no_run
194+
/// use buddy_slab_allocator::GlobalAllocator;
195+
///
196+
/// const PAGE_SIZE: usize = 0x1000;
197+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
198+
/// allocator.init(0x8000_0000, 16 * 1024 * 1024).unwrap();
199+
/// ```
190200
pub fn init(&self, start_vaddr: usize, size: usize) -> AllocResult<()> {
191201
if size <= MIN_HEAP_SIZE {
192202
return Err(AllocError::InvalidParam);
@@ -243,6 +253,24 @@ impl<const PAGE_SIZE: usize> GlobalAllocator<PAGE_SIZE> {
243253
}
244254

245255
/// Smart allocation based on size
256+
///
257+
/// Small allocations (≤2048 bytes) use slab allocator,
258+
/// larger allocations use page allocator.
259+
///
260+
/// # Examples
261+
///
262+
/// ```no_run
263+
/// use buddy_slab_allocator::GlobalAllocator;
264+
/// use core::alloc::Layout;
265+
///
266+
/// const PAGE_SIZE: usize = 0x1000;
267+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
268+
/// allocator.init(0x8000_0000, 16 * 1024 * 1024).unwrap();
269+
///
270+
/// let layout = Layout::from_size_align(64, 8).unwrap();
271+
/// let ptr = allocator.alloc(layout).unwrap();
272+
/// allocator.dealloc(ptr, layout);
273+
/// ```
246274
pub fn alloc(&self, layout: Layout) -> AllocResult<NonNull<u8>> {
247275
if !self.initialized.load(Ordering::SeqCst) {
248276
error!("global allocator: Allocator not initialized");
@@ -300,6 +328,19 @@ impl<const PAGE_SIZE: usize> GlobalAllocator<PAGE_SIZE> {
300328
}
301329

302330
/// Allocate pages
331+
///
332+
/// # Examples
333+
///
334+
/// ```no_run
335+
/// use buddy_slab_allocator::{GlobalAllocator, PageAllocator};
336+
///
337+
/// const PAGE_SIZE: usize = 0x1000;
338+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
339+
/// allocator.init(0x8000_0000, 16 * 1024 * 1024).unwrap();
340+
///
341+
/// let addr = allocator.alloc_pages(4, PAGE_SIZE).unwrap();
342+
/// allocator.dealloc_pages(addr, 4);
343+
/// ```
303344
pub fn alloc_pages(&self, num_pages: usize, alignment: usize) -> AllocResult<usize> {
304345
if !self.initialized.load(Ordering::SeqCst) {
305346
return Err(AllocError::NoMemory);

allocator/src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,61 @@ pub mod global_allocator;
188188
pub use global_allocator::GlobalAllocator;
189189
#[cfg(feature = "tracking")]
190190
pub use global_allocator::UsageStats;
191+
192+
#[cfg(doc)]
193+
/// Documentation tests and examples
194+
///
195+
/// # Basic Usage
196+
///
197+
/// ```no_run
198+
/// use buddy_slab_allocator::{GlobalAllocator, PageAllocator};
199+
///
200+
/// const PAGE_SIZE: usize = 0x1000;
201+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
202+
///
203+
/// // Initialize with memory region
204+
/// let heap_start = 0x8000_0000;
205+
/// let heap_size = 16 * 1024 * 1024; // 16MB
206+
/// allocator.init(heap_start, heap_size).unwrap();
207+
///
208+
/// // Allocate pages
209+
/// let addr = allocator.alloc_pages(4, PAGE_SIZE).unwrap();
210+
/// // Use the allocated memory...
211+
/// allocator.dealloc_pages(addr, 4);
212+
/// ```
213+
///
214+
/// # Small Object Allocation
215+
///
216+
/// ```no_run
217+
/// use buddy_slab_allocator::GlobalAllocator;
218+
/// use core::alloc::Layout;
219+
///
220+
/// const PAGE_SIZE: usize = 0x1000;
221+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
222+
/// allocator.init(0x8000_0000, 16 * 1024 * 1024).unwrap();
223+
///
224+
/// // Small allocations go through slab allocator
225+
/// let layout = Layout::from_size_align(64, 8).unwrap();
226+
/// let ptr = allocator.alloc(layout).unwrap();
227+
/// // Use the allocated memory...
228+
/// allocator.dealloc(ptr, layout);
229+
/// ```
230+
///
231+
/// # Statistics Tracking
232+
///
233+
/// ```no_run
234+
/// # #[cfg(feature = "tracking")]
235+
/// # {
236+
/// use buddy_slab_allocator::GlobalAllocator;
237+
///
238+
/// const PAGE_SIZE: usize = 0x1000;
239+
/// let allocator = GlobalAllocator::<PAGE_SIZE>::new();
240+
/// allocator.init(0x8000_0000, 16 * 1024 * 1024).unwrap();
241+
///
242+
/// let stats = allocator.get_stats();
243+
/// println!("Total pages: {}", stats.total_pages);
244+
/// println!("Used pages: {}", stats.used_pages);
245+
/// println!("Free pages: {}", stats.free_pages);
246+
/// # }
247+
/// ```
248+
pub mod _examples {}

allocator/src/page_allocator.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,59 @@ mod tests {
512512
assert_eq!(info2.unwrap().part_count, 3);
513513
}
514514
}
515+
516+
#[cfg(test)]
517+
mod unit_tests {
518+
use super::*;
519+
use alloc::alloc::{alloc, dealloc};
520+
use core::alloc::Layout;
521+
522+
const TEST_HEAP_SIZE: usize = 16 * 1024 * 1024;
523+
const TEST_PAGE_SIZE: usize = 0x1000;
524+
525+
fn alloc_test_heap(size: usize) -> (*mut u8, Layout) {
526+
let layout = Layout::from_size_align(size, TEST_PAGE_SIZE).unwrap();
527+
let ptr = unsafe { alloc(layout) };
528+
assert!(!ptr.is_null());
529+
(ptr, layout)
530+
}
531+
532+
fn dealloc_test_heap(ptr: *mut u8, layout: Layout) {
533+
unsafe { dealloc(ptr, layout) };
534+
}
535+
536+
#[test]
537+
fn test_composite_allocator_basic() {
538+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
539+
let heap_addr = heap_ptr as usize;
540+
541+
let mut allocator = CompositePageAllocator::<TEST_PAGE_SIZE>::new();
542+
allocator.init(heap_addr, TEST_HEAP_SIZE);
543+
544+
let addr1 = allocator.alloc_pages(1, TEST_PAGE_SIZE).unwrap();
545+
let addr2 = allocator.alloc_pages(4, TEST_PAGE_SIZE).unwrap();
546+
547+
assert!(addr1 >= heap_addr && addr1 < heap_addr + TEST_HEAP_SIZE);
548+
assert!(addr2 >= heap_addr && addr2 < heap_addr + TEST_HEAP_SIZE);
549+
550+
allocator.dealloc_pages(addr1, 1);
551+
allocator.dealloc_pages(addr2, 4);
552+
553+
dealloc_test_heap(heap_ptr, heap_layout);
554+
}
555+
556+
#[test]
557+
fn test_composite_allocator_alignment() {
558+
let (heap_ptr, heap_layout) = alloc_test_heap(TEST_HEAP_SIZE);
559+
let heap_addr = heap_ptr as usize;
560+
561+
let mut allocator = CompositePageAllocator::<TEST_PAGE_SIZE>::new();
562+
allocator.init(heap_addr, TEST_HEAP_SIZE);
563+
564+
let addr = allocator.alloc_pages(1, TEST_PAGE_SIZE * 4).unwrap();
565+
assert_eq!(addr & (TEST_PAGE_SIZE * 4 - 1), 0);
566+
567+
allocator.dealloc_pages(addr, 1);
568+
dealloc_test_heap(heap_ptr, heap_layout);
569+
}
570+
}

allocator/src/slab/slab_byte_allocator.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,27 @@ mod tests {
228228
None
229229
);
230230
}
231+
232+
#[test]
233+
fn test_size_class_boundaries() {
234+
// Test all size class boundaries
235+
assert_eq!(SizeClass::Bytes8.size(), 8);
236+
assert_eq!(SizeClass::Bytes16.size(), 16);
237+
assert_eq!(SizeClass::Bytes32.size(), 32);
238+
assert_eq!(SizeClass::Bytes64.size(), 64);
239+
assert_eq!(SizeClass::Bytes128.size(), 128);
240+
assert_eq!(SizeClass::Bytes256.size(), 256);
241+
assert_eq!(SizeClass::Bytes512.size(), 512);
242+
assert_eq!(SizeClass::Bytes1024.size(), 1024);
243+
assert_eq!(SizeClass::Bytes2048.size(), 2048);
244+
}
245+
246+
#[test]
247+
fn test_size_class_alignment_limits() {
248+
// Alignment too large should return None
249+
assert_eq!(
250+
SizeClass::from_layout(Layout::from_size_align(64, 4096).unwrap()),
251+
None
252+
);
253+
}
231254
}

0 commit comments

Comments
 (0)