Skip to content

Commit e87a81b

Browse files
committed
feat(test): add alloc tests
1 parent 7aaa035 commit e87a81b

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

page_table_multiarch/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ riscv = { version = "0.14", default-features = false }
3030

3131
[package.metadata.docs.rs]
3232
rustc-args = ["--cfg", "doc"]
33+
34+
[dev-dependencies]
35+
rand = { version = "0.9.1", default-features = false, features = ["small_rng"] }
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use std::{
2+
alloc::{self, Layout},
3+
cell::RefCell,
4+
collections::HashSet,
5+
marker::PhantomData,
6+
};
7+
8+
use memory_addr::{PhysAddr, VirtAddr};
9+
use page_table_entry::{GenericPTE, MappingFlags};
10+
use page_table_multiarch::{PageSize, PageTable64, PagingHandler, PagingMetaData, PagingResult};
11+
use rand::{Rng, SeedableRng, rngs::SmallRng};
12+
13+
const PAGE_LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(4096, 4096) };
14+
15+
thread_local! {
16+
static ALLOCATED: RefCell<HashSet<usize>> = RefCell::default();
17+
}
18+
struct TrackPagingHandler<M: PagingMetaData>(PhantomData<M>);
19+
impl<M: PagingMetaData> PagingHandler for TrackPagingHandler<M> {
20+
fn alloc_frame() -> Option<PhysAddr> {
21+
let ptr = unsafe { alloc::alloc(PAGE_LAYOUT) } as usize;
22+
assert!(
23+
ptr <= M::PA_MAX_ADDR,
24+
"allocated frame address exceeds PA_MAX_ADDR"
25+
);
26+
ALLOCATED.with_borrow_mut(|it| it.insert(ptr));
27+
Some(PhysAddr::from_usize(ptr))
28+
}
29+
30+
fn dealloc_frame(paddr: PhysAddr) {
31+
let ptr = paddr.as_usize();
32+
ALLOCATED.with_borrow_mut(|it| {
33+
assert!(it.remove(&ptr), "dealloc a frame that was not allocated");
34+
});
35+
unsafe {
36+
alloc::dealloc(ptr as _, PAGE_LAYOUT);
37+
}
38+
}
39+
40+
fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
41+
if paddr.as_usize() == 0 {
42+
panic!();
43+
}
44+
VirtAddr::from_usize(paddr.as_usize())
45+
}
46+
}
47+
48+
fn run_test_for<M: PagingMetaData<VirtAddr = VirtAddr>, PTE: GenericPTE>() -> PagingResult<()> {
49+
ALLOCATED.with_borrow_mut(|it| {
50+
it.clear();
51+
});
52+
53+
let vaddr_mask = ((1u64 << M::VA_MAX_BITS) - 1) & !0xfff;
54+
55+
let mut table = PageTable64::<M, PTE, TrackPagingHandler<M>>::try_new().unwrap();
56+
let mut pages = HashSet::new();
57+
let mut rng = SmallRng::seed_from_u64(1234);
58+
for _ in 0..2048 {
59+
if rng.random_ratio(3, 4) || pages.is_empty() {
60+
// insert a mapping
61+
let addr = loop {
62+
let addr = rng.random::<u64>() & vaddr_mask;
63+
if pages.insert(addr) {
64+
break addr;
65+
}
66+
};
67+
table
68+
.map(
69+
VirtAddr::from_usize(addr as usize),
70+
PhysAddr::from_usize((rng.random::<u64>() & vaddr_mask) as usize),
71+
PageSize::Size4K,
72+
MappingFlags::READ | MappingFlags::WRITE,
73+
)?
74+
.ignore();
75+
} else {
76+
// remove a mapping
77+
let addr = *pages.iter().next().unwrap();
78+
table.unmap(VirtAddr::from_usize(addr as usize))?.2.ignore();
79+
pages.remove(&addr);
80+
}
81+
}
82+
83+
drop(table);
84+
assert_eq!(
85+
ALLOCATED.with_borrow(|it| it.len()),
86+
0,
87+
"Some frames were not deallocated"
88+
);
89+
90+
Ok(())
91+
}
92+
93+
#[test]
94+
fn test_dealloc() -> PagingResult<()> {
95+
#[cfg(target_arch = "x86_64")]
96+
run_test_for::<
97+
page_table_multiarch::x86_64::X64PagingMetaData,
98+
page_table_entry::x86_64::X64PTE,
99+
>()?;
100+
101+
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
102+
{
103+
run_test_for::<
104+
page_table_multiarch::riscv::Sv39MetaData<VirtAddr>,
105+
page_table_entry::riscv::Rv64PTE,
106+
>()?;
107+
run_test_for::<
108+
page_table_multiarch::riscv::Sv48MetaData<VirtAddr>,
109+
page_table_entry::riscv::Rv64PTE,
110+
>()?;
111+
}
112+
113+
#[cfg(target_arch = "aarch64")]
114+
run_test_for::<
115+
page_table_multiarch::aarch64::A64PagingMetaData,
116+
page_table_entry::aarch64::A64PTE,
117+
>()?;
118+
119+
#[cfg(target_arch = "loongarch64")]
120+
run_test_for::<
121+
page_table_multiarch::loongarch64::LA64MetaData,
122+
page_table_entry::loongarch64::LA64PTE,
123+
>()?;
124+
125+
Ok(())
126+
}

0 commit comments

Comments
 (0)