Files
renderbug-bike/src/tracing.rs

178 lines
4.1 KiB
Rust

#![allow(static_mut_refs)]
use log::*;
use crate::logging::RenderbugLogger;
#[derive(Debug)]
struct TracedTask {
id: u32,
name: &'static str,
priority: u32,
running: bool,
ready: bool
}
impl TracedTask {
fn new(id: u32) -> Self {
Self {
id,
name: "<unnamed task>",
priority: 0,
running: false,
ready: false
}
}
}
pub struct Tracer {}
struct TracerState {
tasks: [core::mem::MaybeUninit<TracedTask>; 16],
num_tasks: usize,
}
static mut TRACER_STATE: TracerState = TracerState::new();
impl TracerState {
const fn new() -> Self {
Self {
tasks: [const { core::mem::MaybeUninit::uninit() }; 16],
num_tasks: 0,
}
}
fn get_task(&mut self, id: u32) -> &mut TracedTask {
for i in 0..self.num_tasks {
let info = unsafe { &mut *self.tasks[i].as_mut_ptr() };
if info.id == id {
return info;
}
}
// Otherwise, we register a new task
if self.num_tasks < self.tasks.len() {
self.tasks[self.num_tasks].write(TracedTask::new(id));
self.num_tasks += 1;
} else {
panic!("too many tasks registered");
}
unsafe { &mut *self.tasks[self.num_tasks - 1].as_mut_ptr() }
}
}
impl rtos_trace::RtosTrace for Tracer {
fn start() {
warn!("rtos start");
}
fn stop() {
warn!("rtos stop");
}
fn task_new(id: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
warn!("rtos new task {task:?}");
}
fn task_send_info(id: u32, info: rtos_trace::TaskInfo) {
let task = unsafe { TRACER_STATE.get_task(id) };
task.name = info.name;
task.priority = info.priority;
warn!("rtos task info for task {task:?}");
}
fn task_new_stackless(id: u32, name: &'static str, priority: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
task.name = name;
task.priority = priority;
warn!("rtos new task {task:?} {name}");
}
fn task_terminate(id: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
warn!("rtos terminate {task:?}")
}
fn task_exec_begin(id: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
task.running = true;
warn!("rtos exec {task:?}")
}
fn task_exec_end() {
warn!("rtos exec end");
}
fn task_ready_begin(id: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
task.ready = true;
warn!("rtos ready {task:?}")
}
fn task_ready_end(id: u32) {
let task = unsafe { TRACER_STATE.get_task(id) };
task.ready = false;
warn!("rtos suspend {task:?}")
}
fn system_idle() {
warn!("rtos system idle");
}
fn isr_enter() {
warn!("rtos isr enter");
}
fn isr_exit() {
warn!("rtos isr exit");
}
fn isr_exit_to_scheduler() {
warn!("rtos isr exit to scheduler");
}
fn name_marker(id: u32, name: &'static str) {
warn!("rtos name marker {id}: {name}");
}
fn marker(id: u32) {
warn!("rtos marker {}", Self::name_for_marker(id));
}
fn marker_begin(id: u32) {
match id {
//1..2 => trace!("rtos marker begin {}", Self::name_for_marker(id)),
_ => {
warn!("rtos marker begin {}", Self::name_for_marker(id));
RenderbugLogger::set_level(LevelFilter::Trace);
}
}
}
fn marker_end(id: u32) {
match id {
//1..2 => trace!("rtos marker end {}", Self::name_for_marker(id)),
_ => {
warn!("rtos marker end {}", Self::name_for_marker(id));
RenderbugLogger::reset_level();
},
}
}
}
impl Tracer {
const fn name_for_marker(id: u32) -> &'static str {
match id {
0 => "run scheduler",
1 => "yield task",
2 => "timer tick",
3 => "process timer queue",
4 => "process embassy timer queue",
_ => "unknown",
}
}
}