mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-05-24 08:55:20 -04:00
libkernel: region: add new utility functions
Add the following to all memory region variants: - `is_empty()`: Return true if the region has zero size. - `cap_size()`: Reduces the size if the given size < current. - `shrink_start()`: Move start address forward, while shrinking the region.
This commit is contained in:
@@ -59,6 +59,11 @@ impl<T: MemKind> MemoryRegion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this memory region is empty.
|
||||
pub fn is_empty(self) -> bool {
|
||||
self.size == 0
|
||||
}
|
||||
|
||||
/// Create a memory region from a start and end address.
|
||||
///
|
||||
/// The size is calculated as `end - start`. No alignment is enforced.
|
||||
@@ -71,6 +76,27 @@ impl<T: MemKind> MemoryRegion<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Cap the size of the region. If `max_size < self.size`, the region is
|
||||
/// shrunk.
|
||||
pub fn cap_size(self, max_size: usize) -> Self {
|
||||
if max_size < self.size {
|
||||
Self::new(self.start_address(), max_size)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Shrink this region by moving the start address 'forward' by `x` bytes.
|
||||
///
|
||||
/// If `x` moves the start address beyond the end of the region, it
|
||||
/// saturates on the boundary and becomes empty.
|
||||
pub fn shrink_start(self, x: usize) -> Self {
|
||||
Self {
|
||||
address: self.start_address().add_bytes(x),
|
||||
size: self.size.saturating_sub(x),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a new region with the same size but a different start address.
|
||||
pub fn with_start_address(mut self, new_start: Address<T, ()>) -> Self {
|
||||
self.address = new_start;
|
||||
@@ -676,6 +702,83 @@ mod tests {
|
||||
assert_eq!(main.punch_hole(hole), (Some(main), None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_empty_zero_size() {
|
||||
let r = region(0x1000, 0);
|
||||
assert!(r.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_empty_nonzero_size() {
|
||||
let r = region(0x1000, 0x10);
|
||||
assert!(!r.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_empty_empty_constructor() {
|
||||
assert!(PhysMemoryRegion::empty().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cap_size_below_current() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let capped = r.cap_size(0x50);
|
||||
assert_eq!(capped.start_address().value(), 0x1000);
|
||||
assert_eq!(capped.size(), 0x50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cap_size_equal_to_current() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let capped = r.cap_size(0x100);
|
||||
assert_eq!(capped, r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cap_size_above_current() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let capped = r.cap_size(0x200);
|
||||
assert_eq!(capped, r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cap_size_to_zero() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let capped = r.cap_size(0);
|
||||
assert_eq!(capped.start_address().value(), 0x1000);
|
||||
assert!(capped.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_start_within_bounds() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let shrunk = r.shrink_start(0x40);
|
||||
assert_eq!(shrunk.start_address().value(), 0x1040);
|
||||
assert_eq!(shrunk.size(), 0xC0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_start_exact_size() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let shrunk = r.shrink_start(0x100);
|
||||
assert_eq!(shrunk.start_address().value(), 0x1100);
|
||||
assert!(shrunk.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_start_beyond_end_saturates() {
|
||||
let r = region(0x1000, 0x100);
|
||||
let shrunk = r.shrink_start(0x200);
|
||||
assert_eq!(shrunk.start_address().value(), 0x1200);
|
||||
assert!(shrunk.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_start_zero() {
|
||||
let r = region(0x1000, 0x100);
|
||||
assert_eq!(r.shrink_start(0), r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_punch_hole_disjoint() {
|
||||
// Hole is completely far away (after)
|
||||
|
||||
Reference in New Issue
Block a user