mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-01 21:59:41 +00:00
Add a simple rust global allocator to each component.
- add a linked_list_allocator::LockedHeap instance to each component that might want to allocate memory and init the allocator with a fixed-size memory block in the component post_init hook - add an alloc_test shell command that exercises the allocator This does not dynamically add memory or support sharing memory between components; this is an intermediate step to simplify bringing in crates that want to allocate memory (e.g. hashbrown).. Change-Id: Idaf11fb5d4999218c75bf932133df24de35e3053 GitOrigin-RevId: 7c9b14bf9463239ce030c374b58a140f0835759e
This commit is contained in:
parent
e4973577ec
commit
8d7e4bf44a
49
apps/system/components/DebugConsole/Cargo.lock
generated
49
apps/system/components/DebugConsole/Cargo.lock
generated
@ -1,49 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7313c0d620d0cb4dbd9d019e461a4beb501071ff46ec0ab933efb4daa76d73e3"
|
||||
|
||||
[[package]]
|
||||
name = "kata-debug-console"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kata-shell",
|
||||
"kata-uart-client",
|
||||
"panic-halt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kata-io"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "kata-line-reader"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kata-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kata-shell"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kata-io",
|
||||
"kata-line-reader",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kata-uart-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cty",
|
||||
"kata-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic-halt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
@ -9,6 +9,7 @@ description = "Kata OS DebugConsole"
|
||||
panic-halt = "0.2.0"
|
||||
kata-shell = { path = "../kata-shell" }
|
||||
kata-uart-client = { path = "../kata-uart-client" }
|
||||
linked_list_allocator = "0.9"
|
||||
|
||||
[lib]
|
||||
name = "kata_debug_console"
|
||||
|
@ -12,11 +12,29 @@
|
||||
// std:: requires at least an allocator, which Kata does not have yet. For now
|
||||
// the CLI will be implemented with only core::.
|
||||
#![no_std]
|
||||
// NB: not really what we want but resolves undefineds for now
|
||||
#![feature(default_alloc_error_handler)]
|
||||
|
||||
extern crate panic_halt;
|
||||
|
||||
use kata_shell;
|
||||
use kata_uart_client;
|
||||
use linked_list_allocator::LockedHeap;
|
||||
|
||||
#[global_allocator]
|
||||
static KATA_ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
#[no_mangle]
|
||||
// NB: use post_init insted of pre_init so syslog interface is setup
|
||||
pub extern "C" fn post_init() {
|
||||
// TODO(sleffler): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 16 * 1024] = [0; 16 * 1024];
|
||||
unsafe {
|
||||
KATA_ALLOCATOR
|
||||
.lock()
|
||||
.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point for DebugConsole. Runs the shell with UART IO.
|
||||
#[no_mangle]
|
||||
|
@ -43,8 +43,8 @@ impl From<fmt::Error> for CommandError {
|
||||
|
||||
/// Read-eval-print loop for the DebugConsole command line interface.
|
||||
pub fn repl(output: &mut dyn io::Write, input: &mut dyn io::Read) -> ! {
|
||||
let _ = write!(output, "DebugConsole::repl()\n");
|
||||
let mut line_reader = LineReader::new();
|
||||
let _ = write!(output, "DebugConsole::repl()\n");
|
||||
let mut line_reader = LineReader::new();
|
||||
loop {
|
||||
const PROMPT: &str = "KATA_PROMPT> ";
|
||||
let _ = output.write_str(PROMPT);
|
||||
@ -75,6 +75,7 @@ fn dispatch_command(cmdline: &str, output: &mut dyn io::Write) {
|
||||
"add" => add_command(&mut args, output),
|
||||
"clear" => clear_command(output),
|
||||
"ps" => ps_command(),
|
||||
"alloc_test" => alloc_test_command(output),
|
||||
_ => Err(CommandError::UnknownCommand),
|
||||
};
|
||||
if let Err(e) = result {
|
||||
@ -103,8 +104,12 @@ fn echo_command(cmdline: &str, output: &mut dyn io::Write) -> Result<(), Command
|
||||
|
||||
/// Implements a "ps" command that dumps seL4 scheduler state to the console.
|
||||
fn ps_command() -> Result<(), CommandError> {
|
||||
extern "C" { fn sel4debug_dump_scheduler(); }
|
||||
unsafe { sel4debug_dump_scheduler(); }
|
||||
extern "C" {
|
||||
fn sel4debug_dump_scheduler();
|
||||
}
|
||||
unsafe {
|
||||
sel4debug_dump_scheduler();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -133,3 +138,40 @@ fn add_command(
|
||||
fn clear_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
||||
Ok(output.write_str("\x1b\x63")?)
|
||||
}
|
||||
|
||||
/// Implements a command that tests facilities that use the global allocator.
|
||||
/// Shamelessly cribbed from https://os.phil-opp.com/heap-allocation/
|
||||
fn alloc_test_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
||||
extern crate alloc;
|
||||
use alloc::{boxed::Box, rc::Rc, vec, vec::Vec};
|
||||
|
||||
// allocate a number on the heap
|
||||
let heap_value = Box::new(41);
|
||||
writeln!(output, "heap_value at {:p}", heap_value).expect("Box failed");
|
||||
|
||||
// create a dynamically sized vector
|
||||
let mut vec = Vec::new();
|
||||
for i in 0..500 {
|
||||
vec.push(i);
|
||||
}
|
||||
writeln!(output, "vec at {:p}", vec.as_slice()).expect("Vec failed");
|
||||
|
||||
// create a reference counted vector -> will be freed when count reaches 0
|
||||
let reference_counted = Rc::new(vec![1, 2, 3]);
|
||||
let cloned_reference = reference_counted.clone();
|
||||
writeln!(
|
||||
output,
|
||||
"current reference count is {}",
|
||||
Rc::strong_count(&cloned_reference)
|
||||
)
|
||||
.expect("Rc 1 failed");
|
||||
core::mem::drop(reference_counted);
|
||||
writeln!(
|
||||
output,
|
||||
"reference count is {} now",
|
||||
Rc::strong_count(&cloned_reference)
|
||||
)
|
||||
.expect("Rc 2 failed");
|
||||
|
||||
Ok(writeln!(output, "All tests passed!")?)
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
cstr_core = { version = "0.2.3", default-features = false }
|
||||
kata-proc-common = { path = "../kata-proc-common" }
|
||||
linked_list_allocator = "0.9"
|
||||
panic-halt = "0.2.0"
|
||||
|
||||
[lib]
|
||||
|
@ -4,30 +4,38 @@
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![feature(const_fn_trait_bound)] // NB: for ProcessManager::empty using manager: None
|
||||
#![feature(default_alloc_error_handler)]
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern crate panic_halt;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use core::marker::Sync;
|
||||
use cstr_core::CStr;
|
||||
use linked_list_allocator::LockedHeap;
|
||||
|
||||
use kata_proc_common as proc;
|
||||
use proc::*;
|
||||
|
||||
// Prints/logs a message to the console.
|
||||
// Temporary workaround for LoggerInterface not working
|
||||
fn syslog(_level: i32, msg: &str) {
|
||||
// Print |str| on the consule using the SeL4 debug syscall.
|
||||
// NB: for now the message must be explicitly \0-terminated.
|
||||
fn sel4_putstr(msg: &str) {
|
||||
extern "C" {
|
||||
fn sel4debug_put_string(msg: *const cstr_core::c_char);
|
||||
}
|
||||
unsafe {
|
||||
sel4debug_put_string(CStr::from_bytes_with_nul(msg.as_bytes()).unwrap().as_ptr());
|
||||
}
|
||||
#[global_allocator]
|
||||
static KATA_ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
#[no_mangle]
|
||||
// NB: use post_init insted of pre_init so logger is setup
|
||||
pub extern "C" fn post_init() {
|
||||
// TODO(sleffler): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 16 * 1024] = [0; 16 * 1024];
|
||||
unsafe {
|
||||
KATA_ALLOCATOR
|
||||
.lock()
|
||||
.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
}
|
||||
sel4_putstr(msg); // NB:assumes caller includes \0
|
||||
}
|
||||
|
||||
// TODO(sleffler): move to init or similar if a thread isn't needed
|
||||
#[no_mangle]
|
||||
pub extern "C" fn run() {
|
||||
// Setup the userland address spaces, lifecycles, and system introspection
|
||||
// for third-party applications.
|
||||
}
|
||||
|
||||
// Bundle state tracks start/stop operations.
|
||||
@ -175,14 +183,6 @@ impl<'a> ProcessControlInterface for ProcessManager<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sleffler): move to init or similar if a thread isn't needed
|
||||
#[no_mangle]
|
||||
pub extern "C" fn run() {
|
||||
// Setup the userland address spaces, lifecycles, and system introspection
|
||||
// for third-party applications.
|
||||
syslog(0, "ProcessManager::run\n\0");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
Loading…
Reference in New Issue
Block a user