frame-alloc 0.1.0

A no_std, dependency-free, const-constructible physical frame allocator for kernels
Documentation
use crate::PageSize;
use core::num::NonZeroUsize;

const PS_4K: PageSize = PageSize::from_log2(12);

#[test]
fn bytes_matches_shift() {
    for shift in [1u8, 4, 12, 21, 30] {
        assert_eq!(PageSize::from_log2(shift).bytes(), 1usize << shift);
    }
}

#[test]
fn is_aligned_true() {
    assert!(PS_4K.is_aligned(0));
    assert!(PS_4K.is_aligned(PS_4K.bytes()));
    assert!(PS_4K.is_aligned(PS_4K.bytes() * 3));
}

#[test]
fn is_aligned_false() {
    assert!(!PS_4K.is_aligned(1));
    assert!(!PS_4K.is_aligned(PS_4K.bytes() + 1));
}

#[test]
fn align_down_unaligned() {
    let addr = PS_4K.bytes() * 3 + 100;
    assert_eq!(PS_4K.align_down(addr), PS_4K.bytes() * 3);
}

#[test]
fn align_down_already_aligned() {
    let addr = PS_4K.bytes() * 7;
    assert_eq!(PS_4K.align_down(addr), addr);
}

#[test]
fn align_up_unaligned() {
    let addr = PS_4K.bytes() * 3 + 100;
    assert_eq!(PS_4K.align_up(addr), Some(PS_4K.bytes() * 4));
}

#[test]
fn align_up_already_aligned() {
    let addr = PS_4K.bytes() * 5;
    assert_eq!(PS_4K.align_up(addr), Some(addr));
}

#[test]
fn align_up_overflow() {
    // mask = PS_4K.bytes() - 1 = 4095; usize::MAX + 4095 overflows.
    assert_eq!(PS_4K.align_up(usize::MAX), None);
}

#[test]
fn total_bytes_normal() {
    let count = NonZeroUsize::new(5).unwrap();
    assert_eq!(PS_4K.total_bytes(count), Some(PS_4K.bytes() * 5));
}

#[test]
fn total_bytes_overflow() {
    let ps = PageSize::from_log2(1); // 2 bytes
    let count = NonZeroUsize::new(usize::MAX).unwrap();
    // 2 * usize::MAX overflows usize.
    assert_eq!(ps.total_bytes(count), None);
}