move MinSet to utils so that we can test it

thought it would be a good idea to have a unit test for
the MinSet routine (which is used to renormalize the swap
epoch when it overflows). Turns out that was...complicated...
because of the usual problems of test running on host and
the inability to pull through hardware dependencies.
This commit is contained in:
bunnie 2024-05-18 00:22:50 +08:00
parent 44890d72ac
commit fdbbe8d63d
2 changed files with 50 additions and 0 deletions

View file

@ -26,6 +26,7 @@ mod platform;
mod server;
mod services;
mod syscall;
mod utils;
#[cfg(feature = "swap")]
mod swap;

49
kernel/src/utils.rs Normal file
View file

@ -0,0 +1,49 @@
/// Amount of stack-allocated space we allow for a MinSet pass. Increasing this
/// uses more memory, but reduces stack footprint. The current setting of 64
/// should use about 256 bytes of stack, which comfortably fits within the one-page
/// stack limit of the kernel.
pub const RENORM_PASS_SIZE: usize = 64;
/// A helper for assisting with renormalization of the epoch. This uses a small,
/// stack-allocated scratch space, limited by the size of `PASS_SIZE`, to find
/// a set of smallest values within a larger list. We can then use that set to
/// renormalize (e.g. compact down) those values to the smallest possible values,
/// while preserving duplicates and ordering within the overall list.
///
/// `dead_code` is allowed because we want this to be runnable in the set of
/// tests without having to enable the `swap` flag.
#[allow(dead_code)]
pub struct MinSet {
/// Set is ordered from lowest to highest, once fully initialized
pub set: [u32; RENORM_PASS_SIZE],
}
#[allow(dead_code)]
impl MinSet {
pub fn new() -> Self { Self { set: [u32::MAX; RENORM_PASS_SIZE] } }
pub fn insert(&mut self, item: u32) {
// search from lowest to highest for a duplicate
for s in self.set.iter_mut() {
if *s == item {
return;
}
}
// it's not a duplicate
// items are unique and sorted, find a spot to insert, if it deserves a place
if item < self.set[RENORM_PASS_SIZE - 1] {
self.set[RENORM_PASS_SIZE - 1] = item;
self.set.sort_unstable();
}
}
pub fn max(&self) -> u32 { self.set[RENORM_PASS_SIZE - 1] }
pub fn index_of(&self, data: u32) -> Option<usize> {
for (i, &d) in self.set.iter().enumerate() {
if d == data {
return Some(i);
}
}
None
}
}