mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-09-02 14:04:12 +00:00
kata-os-slot-allocator: add optional tracing msgs
Add debug msgs gated by a new "TRACE_OPS" feature. Messages are prefixed by the Camkes component name since each component may have an allocator. Change-Id: Id278bd489a0bedd532f5508c3ebe0101fc749f2c GitOrigin-RevId: f09b0093eac1fd21ac2523808ee3d67a444abeb3
This commit is contained in:
@@ -56,7 +56,7 @@ impl Camkes {
|
|||||||
|
|
||||||
pub fn init_slot_allocator(self: &Camkes, first_slot: seL4_CPtr, last_slot: seL4_CPtr) {
|
pub fn init_slot_allocator(self: &Camkes, first_slot: seL4_CPtr, last_slot: seL4_CPtr) {
|
||||||
unsafe {
|
unsafe {
|
||||||
KATA_CSPACE_SLOTS.init(first_slot, last_slot - first_slot);
|
KATA_CSPACE_SLOTS.init(self.name, first_slot, last_slot - first_slot);
|
||||||
trace!("setup cspace slots: first slot {} free {}",
|
trace!("setup cspace slots: first slot {} free {}",
|
||||||
KATA_CSPACE_SLOTS.base_slot(),
|
KATA_CSPACE_SLOTS.base_slot(),
|
||||||
KATA_CSPACE_SLOTS.free_slots());
|
KATA_CSPACE_SLOTS.free_slots());
|
||||||
@@ -81,12 +81,15 @@ impl Camkes {
|
|||||||
pub fn init_recv_path(self: &mut Camkes, path: &seL4_CPath) {
|
pub fn init_recv_path(self: &mut Camkes, path: &seL4_CPath) {
|
||||||
self.recv_path = *path;
|
self.recv_path = *path;
|
||||||
unsafe { seL4_SetCapReceivePath(path.0, path.1, path.2); }
|
unsafe { seL4_SetCapReceivePath(path.0, path.1, path.2); }
|
||||||
trace!("Cap receive path {:?}", path);
|
trace!("{}: Cap receive path {:?}", self.name, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the path specified with init_recv_path.
|
// Returns the path specified with init_recv_path.
|
||||||
pub fn get_recv_path(self: &Camkes) -> seL4_CPath { self.recv_path }
|
pub fn get_recv_path(self: &Camkes) -> seL4_CPath { self.recv_path }
|
||||||
|
|
||||||
|
// Returns the component name.
|
||||||
|
pub fn get_name(self: &Camkes) -> &'static str { self.name }
|
||||||
|
|
||||||
// Returns the current receive path from the IPCBuffer.
|
// Returns the current receive path from the IPCBuffer.
|
||||||
pub fn get_current_recv_path(self: &Camkes) -> seL4_CPath {
|
pub fn get_current_recv_path(self: &Camkes) -> seL4_CPath {
|
||||||
unsafe { seL4_GetCapReceivePath() }
|
unsafe { seL4_GetCapReceivePath() }
|
||||||
|
@@ -6,7 +6,12 @@ version = "0.1.0"
|
|||||||
authors = ["Sam Leffler <sleffler@google.com>"]
|
authors = ["Sam Leffler <sleffler@google.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
TRACE_OPS = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# TODO(sleffler): v1.0 requires rust edition2021
|
# TODO(sleffler): v1.0 requires rust edition2021
|
||||||
bitvec = { version = "0.22", default-features = false, features = ["alloc"] }
|
bitvec = { version = "0.22", default-features = false, features = ["alloc"] }
|
||||||
|
log = "0.4"
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
|
@@ -7,28 +7,34 @@
|
|||||||
|
|
||||||
use bitvec::prelude::*;
|
use bitvec::prelude::*;
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
#[cfg(feature = "TRACE_OPS")]
|
||||||
|
use log::trace;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
struct Slots {
|
struct Slots {
|
||||||
bits: Option<BitBox<Lsb0, u8>>,
|
bits: Option<BitBox<Lsb0, u8>>,
|
||||||
used: usize,
|
used: usize,
|
||||||
|
name: &'static str, // Component name
|
||||||
// TODO(sleffler): maybe track last alloc for O(1) sequential allocations
|
// TODO(sleffler): maybe track last alloc for O(1) sequential allocations
|
||||||
}
|
}
|
||||||
impl Slots {
|
impl Slots {
|
||||||
fn new(size: usize) -> Self {
|
fn new(name: &'static str, size: usize) -> Self {
|
||||||
Slots {
|
Slots {
|
||||||
bits: Some(bitvec![Lsb0, u8; 0; size].into_boxed_bitslice()),
|
bits: Some(bitvec![Lsb0, u8; 0; size].into_boxed_bitslice()),
|
||||||
used: 0,
|
used: 0,
|
||||||
|
name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const fn empty() -> Self {
|
const fn empty() -> Self {
|
||||||
Slots {
|
Slots {
|
||||||
bits: None,
|
bits: None,
|
||||||
used: 0,
|
used: 0,
|
||||||
|
name: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn init(&mut self, size: usize) {
|
fn init(&mut self, name: &'static str, size: usize) {
|
||||||
self.bits = Some(bitvec![Lsb0, u8; 0; size].into_boxed_bitslice());
|
self.bits = Some(bitvec![Lsb0, u8; 0; size].into_boxed_bitslice());
|
||||||
|
self.name = name;
|
||||||
}
|
}
|
||||||
fn used_slots(&self) -> usize { self.used }
|
fn used_slots(&self) -> usize { self.used }
|
||||||
fn free_slots(&self) -> usize {
|
fn free_slots(&self) -> usize {
|
||||||
@@ -67,17 +73,28 @@ impl Slots {
|
|||||||
let bit = bits.first_zero()?;
|
let bit = bits.first_zero()?;
|
||||||
unsafe { bits.set_unchecked(bit, true) };
|
unsafe { bits.set_unchecked(bit, true) };
|
||||||
self.used = self.used + 1;
|
self.used = self.used + 1;
|
||||||
|
#[cfg(feature = "TRACE_OPS")]
|
||||||
|
trace!("{}:alloc {}", self.name, bit);
|
||||||
Some(bit)
|
Some(bit)
|
||||||
} else {
|
} else {
|
||||||
let first_slot = self.bits.as_ref().unwrap().iter_zeros()
|
let first_slot = self.bits.as_ref().unwrap().iter_zeros()
|
||||||
.find(|bit| self.not_any_in_range(bit + 1..bit + count))?;
|
.find(|bit| self.not_any_in_range(bit + 1..bit + count))?;
|
||||||
self.set_range(first_slot..first_slot + count, true);
|
self.set_range(first_slot..first_slot + count, true);
|
||||||
|
#[cfg(feature = "TRACE_OPS")]
|
||||||
|
trace!("{}:alloc {}..{}", self.name, first_slot, first_slot + count);
|
||||||
Some(first_slot)
|
Some(first_slot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn free(&mut self, first_slot: usize, count: usize) {
|
fn free(&mut self, first_slot: usize, count: usize) {
|
||||||
assert!(count <= self.used);
|
#[cfg(feature = "TRACE_OPS")]
|
||||||
|
if count == 1 {
|
||||||
|
trace!("{}:free {}", self.name, first_slot);
|
||||||
|
} else {
|
||||||
|
trace!("{}:free {} count {}", self.name, first_slot, count);
|
||||||
|
}
|
||||||
|
assert!(count <= self.used,
|
||||||
|
"{}: count {} > used {}", self.name, count, self.used);
|
||||||
self.set_range(first_slot..first_slot + count, false);
|
self.set_range(first_slot..first_slot + count, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,9 +109,9 @@ pub static mut KATA_CSPACE_SLOTS: KataSlotAllocator = KataSlotAllocator::empty()
|
|||||||
|
|
||||||
impl KataSlotAllocator {
|
impl KataSlotAllocator {
|
||||||
/// Initializes the Slot state
|
/// Initializes the Slot state
|
||||||
pub fn new(first_slot: usize, size: usize) -> Self {
|
pub fn new(name: &'static str, first_slot: usize, size: usize) -> Self {
|
||||||
KataSlotAllocator {
|
KataSlotAllocator {
|
||||||
slots: Mutex::new(Slots::new(size)),
|
slots: Mutex::new(Slots::new(name, size)),
|
||||||
base_slot: first_slot,
|
base_slot: first_slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +126,9 @@ impl KataSlotAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the Slot state
|
/// Initializes the Slot state
|
||||||
pub unsafe fn init(&mut self, first_slot: usize, size: usize) {
|
pub unsafe fn init(&mut self, name: &'static str, first_slot: usize, size: usize) {
|
||||||
self.base_slot = first_slot;
|
self.base_slot = first_slot;
|
||||||
(*self.slots.lock()).init(size);
|
(*self.slots.lock()).init(name, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the base slot number.
|
/// Returns the base slot number.
|
||||||
@@ -145,7 +162,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_new() {
|
fn test_slots_new() {
|
||||||
let slots = Slots::new(NSLOTS);
|
let slots = Slots::new("new", NSLOTS);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
}
|
}
|
||||||
@@ -154,7 +171,7 @@ mod slot_tests {
|
|||||||
fn test_slots_init() {
|
fn test_slots_init() {
|
||||||
static mut SLOTS: Slots = Slots::empty();
|
static mut SLOTS: Slots = Slots::empty();
|
||||||
unsafe {
|
unsafe {
|
||||||
SLOTS.init(NSLOTS);
|
SLOTS.init("init", NSLOTS);
|
||||||
assert_eq!(SLOTS.used_slots(), 0);
|
assert_eq!(SLOTS.used_slots(), 0);
|
||||||
assert_eq!(SLOTS.free_slots(), NSLOTS);
|
assert_eq!(SLOTS.free_slots(), NSLOTS);
|
||||||
}
|
}
|
||||||
@@ -162,7 +179,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_one() {
|
fn test_slots_one() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("one", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
let first = slots.alloc_first_fit(1).unwrap();
|
let first = slots.alloc_first_fit(1).unwrap();
|
||||||
@@ -175,7 +192,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_one_multi() {
|
fn test_slots_one_multi() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("one_multi", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
let first = slots.alloc_first_fit(1).unwrap();
|
let first = slots.alloc_first_fit(1).unwrap();
|
||||||
@@ -196,7 +213,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_range() {
|
fn test_slots_range() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("range", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
let first = slots.alloc_first_fit(3).unwrap();
|
let first = slots.alloc_first_fit(3).unwrap();
|
||||||
@@ -212,7 +229,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_range_multi() {
|
fn test_slots_range_multi() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("range_multi", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
let first = slots.alloc_first_fit(4).unwrap();
|
let first = slots.alloc_first_fit(4).unwrap();
|
||||||
@@ -232,7 +249,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_range_split_free() {
|
fn test_slots_range_split_free() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("range_split_free", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
let first = slots.alloc_first_fit(4).unwrap();
|
let first = slots.alloc_first_fit(4).unwrap();
|
||||||
@@ -248,7 +265,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_range_split_free_multi() {
|
fn test_slots_range_split_free_multi() {
|
||||||
let mut slots = Slots::new(64);
|
let mut slots = Slots::new("range_split_free_multi", 64);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
|
|
||||||
@@ -272,7 +289,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_empty() {
|
fn test_slots_empty() {
|
||||||
let mut slots = Slots::new(0);
|
let mut slots = Slots::new("empty", 0);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), 0);
|
assert_eq!(slots.free_slots(), 0);
|
||||||
assert!(slots.alloc_first_fit(1).is_none());
|
assert!(slots.alloc_first_fit(1).is_none());
|
||||||
@@ -282,7 +299,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_too_small() {
|
fn test_slots_too_small() {
|
||||||
let mut slots = Slots::new(NSLOTS);
|
let mut slots = Slots::new("too_small", NSLOTS);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
assert!(slots.alloc_first_fit(NSLOTS + 1).is_none());
|
assert!(slots.alloc_first_fit(NSLOTS + 1).is_none());
|
||||||
@@ -290,7 +307,7 @@ mod slot_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slots_oospace() {
|
fn test_slots_oospace() {
|
||||||
let mut slots = Slots::new(4);
|
let mut slots = Slots::new("nospace", 4);
|
||||||
// Allocate 3 of 4 slots
|
// Allocate 3 of 4 slots
|
||||||
let first = slots.alloc_first_fit(3).unwrap();
|
let first = slots.alloc_first_fit(3).unwrap();
|
||||||
assert_eq!(slots.free_slots(), 1);
|
assert_eq!(slots.free_slots(), 1);
|
||||||
@@ -306,7 +323,7 @@ mod slot_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_slots_free_single_invalid() {
|
fn test_slots_free_single_invalid() {
|
||||||
let mut slots = Slots::new(NSLOTS);
|
let mut slots = Slots::new("invalid", NSLOTS);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
// Free an already free slot
|
// Free an already free slot
|
||||||
@@ -316,7 +333,7 @@ mod slot_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_slots_free_hole_invalid() {
|
fn test_slots_free_hole_invalid() {
|
||||||
let mut slots = Slots::new(NSLOTS);
|
let mut slots = Slots::new("free_hole_invalid", NSLOTS);
|
||||||
assert_eq!(slots.used_slots(), 0);
|
assert_eq!(slots.used_slots(), 0);
|
||||||
assert_eq!(slots.free_slots(), NSLOTS);
|
assert_eq!(slots.free_slots(), NSLOTS);
|
||||||
// Allocate the first 4 slots
|
// Allocate the first 4 slots
|
||||||
@@ -339,7 +356,7 @@ mod kata_slot_tests {
|
|||||||
fn setup() {
|
fn setup() {
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
INIT.call_once(|| { unsafe { SLOTS.init(SLOT_RANGE.start, SLOT_RANGE.len()) }; })
|
INIT.call_once(|| { unsafe { SLOTS.init("test", SLOT_RANGE.start, SLOT_RANGE.len()) }; })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Reference in New Issue
Block a user