feat(kernel): per-process budgets (pages, endpoints, notifs, regions) carved from creator, returned on death; init owns pool
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/// Per-process page budget. Every frame charged to a process (user pages
|
||||
/// and its page tables) counts against it.
|
||||
/// A count against a limit: one of a process's budgets (see `budget`).
|
||||
/// For pages, every frame charged to a process (user pages and its page
|
||||
/// tables) counts against it.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Quota {
|
||||
used: usize,
|
||||
@@ -7,8 +8,6 @@ pub struct Quota {
|
||||
}
|
||||
|
||||
impl Quota {
|
||||
pub const DEFAULT_LIMIT: usize = 1024;
|
||||
|
||||
pub const fn new(limit: usize) -> Self {
|
||||
Self { used: 0, limit }
|
||||
}
|
||||
@@ -41,17 +40,19 @@ impl Quota {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_limit(&mut self, limit: usize) -> bool {
|
||||
if limit < self.used {
|
||||
return false;
|
||||
/// Gives up `amount` of the unused limit, for a child to hold.
|
||||
pub fn carve(&mut self, amount: usize) -> bool {
|
||||
match self.limit.checked_sub(amount) {
|
||||
Some(rest) if rest >= self.used => {
|
||||
self.limit = rest;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
self.limit = limit;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Quota {
|
||||
fn default() -> Self {
|
||||
Self::new(Self::DEFAULT_LIMIT)
|
||||
/// Takes back a limit carved out earlier.
|
||||
pub fn refund(&mut self, amount: usize) {
|
||||
self.limit = self.limit.saturating_add(amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,13 @@ fn uncharge_cannot_underflow() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn limit_can_be_raised_but_not_below_usage() {
|
||||
fn only_the_unused_limit_can_be_carved() {
|
||||
let mut q = Quota::new(4);
|
||||
q.charge(3);
|
||||
assert!(!q.set_limit(2));
|
||||
assert!(q.set_limit(10));
|
||||
assert!(q.charge(7));
|
||||
assert!(!q.carve(2));
|
||||
assert_eq!(q.limit(), 4);
|
||||
assert!(q.carve(1));
|
||||
assert!(!q.charge(1));
|
||||
q.refund(1);
|
||||
assert!(q.charge(1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user