Skip to content

Commit

Permalink
feat: add exe and map implementation (#14)
Browse files Browse the repository at this point in the history
* feat(kernel/map): add initial impl of Map

* build(deps): update deps

* feat(kernel): add implementation for exe and map

* docs(contributing): instruct to use trace! instead of println!

* feat(kernel): add more missing functions

* test(kernel): add tests
  • Loading branch information
arunanshub authored Sep 28, 2024
1 parent 7c9aaf3 commit 872cb6a
Show file tree
Hide file tree
Showing 12 changed files with 559 additions and 43 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

TODO: add welcoming message

- Use `tracing::debug!()` macro in place of `println!`/`eprintln!`. In other words, wherever you would use
a `println!`, just use `debug!` instead.
- Use `tracing::trace!()` macro in place of `println!`/`eprintln!`. In other words, wherever you would use
a `println!`, just use `trace!` instead.

- Use [`pre-commit`](https://pre-commit.com) to perform checks before committing. Install pre-commit hooks
by running `pre-commit install`.
58 changes: 58 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ edition = "2021"

[dependencies]
config = { version = "0.1.0", path = "../config" }
educe = { version = "0.6.0", default-features = false, features = ["Debug", "Eq", "Hash", "Ord", "PartialEq", "PartialOrd"] }
libc = "0.2.159"
parking_lot = "0.12.3"
procfs = "0.16.0"
sysinfo = "0.31.4"
thiserror.workspace = true
tokio = { version = "1.40.0", features = ["sync", "time"] }
tracing.workspace = true

[dev-dependencies]
pretty_assertions = "1.4.1"
proptest.workspace = true
rand = "0.8.5"

[lints]
workspace = true
7 changes: 7 additions & 0 deletions crates/kernel/proptest-regressions/exe/mod.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 8ee6fbaff9a6799ce9c76e546e1706ffd7862b73a9b6c632f256c942ab4cad70 # shrinks to exemaps = {ExeMap { map: Map { inner: MapInner { path: "", offset: 0, length: 12812496297095135152, runtime: Mutex { data: RuntimeStats { lnprob: 0.0, seq: 0, block: 0 } } } }, prob: 1.0 }, ExeMap { map: Map { inner: MapInner { path: "", offset: 0, length: 5634247776614416464, runtime: Mutex { data: RuntimeStats { lnprob: 0.0, seq: 0, block: 0 } } } }, prob: 1.0 }}
9 changes: 9 additions & 0 deletions crates/kernel/proptest-regressions/map/mod.txt

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions crates/kernel/src/exe/inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#![allow(clippy::mutable_key_type)]

use crate::ExeMap;
use educe::Educe;
use std::{collections::HashSet, path::PathBuf};

#[derive(Default, Clone, Educe)]
#[educe(Debug)]
pub struct ExeInner {
pub path: PathBuf,

#[educe(Debug(ignore))]
pub exemaps: HashSet<ExeMap>,

pub size: usize,

pub seq: u64,

pub time: u64,

pub update_time: Option<u64>,

pub running_timestamp: Option<u64>,

pub change_timestamp: u64,

pub lnprob: f32,
}

impl ExeInner {
pub fn new(path: impl Into<PathBuf>) -> Self {
Self {
path: path.into(),
..Default::default()
}
}

pub fn with_change_timestamp(&mut self, change_timestamp: u64) -> &mut Self {
self.change_timestamp = change_timestamp;
self
}

pub fn with_running(&mut self, last_running_timestamp: u64) -> &mut Self {
self.update_time.replace(last_running_timestamp);
self.running_timestamp.replace(last_running_timestamp);
self
}

pub fn with_exemaps(&mut self, exemaps: HashSet<ExeMap>) -> &mut Self {
self.exemaps = exemaps;
let size: usize = self
.exemaps
.iter()
.map(|map| map.map.length())
.fold(0usize, |acc, x| acc.wrapping_add(x));
self.size = self.size.wrapping_add(size);
self
}

pub const fn is_running(&self, last_running_timestamp: u64) -> bool {
if let Some(running_timestamp) = self.running_timestamp {
running_timestamp >= last_running_timestamp
} else {
0 == last_running_timestamp
}
}

pub fn bid_in_maps(&self, last_running_timestamp: u64) {
if self.is_running(last_running_timestamp) {
self.exemaps.iter().for_each(|v| v.map.increase_lnprob(1.));
} else {
self.exemaps
.iter()
.for_each(|v| v.map.set_lnprob(self.lnprob));
}
}
}
112 changes: 111 additions & 1 deletion crates/kernel/src/exe/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,111 @@
pub struct Exe {}
#![allow(clippy::mutable_key_type)]

mod inner;

use crate::ExeMap;
use inner::ExeInner;
use parking_lot::Mutex;
use std::{collections::HashSet, path::PathBuf, sync::Arc};

#[derive(Debug, Default, Clone)]
pub struct Exe(Arc<Mutex<ExeInner>>);

impl Exe {
pub fn new(path: impl Into<PathBuf>) -> Self {
Self(Arc::new(Mutex::new(ExeInner::new(path))))
}
pub fn with_change_timestamp(self, change_timestamp: u64) -> Self {
self.0.lock().with_change_timestamp(change_timestamp);
self
}

pub fn with_running(self, last_running_timestamp: u64) -> Self {
self.0.lock().with_running(last_running_timestamp);
self
}

pub fn with_exemaps(self, exemaps: HashSet<ExeMap>) -> Self {
self.0.lock().with_exemaps(exemaps);
self
}

pub fn path(&self) -> PathBuf {
self.0.lock().path.clone()
}

pub fn lnprob(&self) -> f32 {
self.0.lock().lnprob
}

pub fn zero_lnprob(&self) {
self.0.lock().lnprob = 0.0;
}

pub fn size(&self) -> usize {
self.0.lock().size
}

pub fn is_running(&self, last_running_timestamp: u64) -> bool {
self.0.lock().is_running(last_running_timestamp)
}

pub fn update_running_timestamp(&self, running_timestamp: u64) {
self.0.lock().running_timestamp.replace(running_timestamp);
}

pub fn update_change_timestamp(&self, change_timestamp: u64) {
self.0.lock().change_timestamp = change_timestamp;
}

pub fn update_time(&self, time: u64) {
self.0.lock().time = time;
}

pub fn set_seq(&self, seq: u64) {
self.0.lock().seq = seq;
}

pub fn bid_in_maps(&self, last_running_timestamp: u64) {
self.0.lock().bid_in_maps(last_running_timestamp);
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{ExeMap, Map};
use pretty_assertions::assert_eq;
use prop::collection::hash_set;
use proptest::prelude::*;

prop_compose! {
fn arbitrary_map()(
path in ".*",
offset in 0..usize::MAX,
length in 0..usize::MAX,
) -> Map {
Map::new(path, offset, length)
}
}

prop_compose! {
// create arbitrary ExeMap from arbitrary Map
fn arbitrary_exemap()(map in arbitrary_map()) -> ExeMap {
ExeMap::new(map)
}
}

proptest! {
#[test]
fn exe_sums_map_sizes(exemaps in hash_set(arbitrary_exemap(), 0..2000)) {
let map_sizes: usize = exemaps
.iter()
.map(|m| m.map.length())
.fold(0usize, |acc, x| acc.wrapping_add(x));
let exe = Exe::new("foo").with_exemaps(exemaps);
let exe_size = exe.size();

assert_eq!(exe_size, map_sizes);
}
}
}
29 changes: 29 additions & 0 deletions crates/kernel/src/exemap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::Map;
use educe::Educe;

#[derive(Debug, Default, Clone, Educe)]
#[educe(Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ExeMap {
pub map: Map,

#[educe(Eq(ignore), Ord(ignore), Hash(ignore))]
pub prob: f32,
}

impl ExeMap {
pub fn new(map: Map) -> Self {
Self { map, prob: 1.0 }
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn exemap_prob_always_1() {
let map = Map::new("test", 0, 0);
let exe_map = ExeMap::new(map);
assert_eq!(exe_map.prob, 1.0);
}
}
9 changes: 7 additions & 2 deletions crates/kernel/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
mod error;
pub mod exe;
pub mod state;
mod exe;
mod exemap;
mod map;
mod state;
pub mod utils;

pub use error::Error;
pub use exe::Exe;
pub use exemap::ExeMap;
pub use map::{Map, RuntimeStats};
pub use state::State;
Loading

0 comments on commit 872cb6a

Please sign in to comment.