[PERF] Runtime Introspection Syscalls

This commit is contained in:
bQUARKz 2026-04-19 08:49:04 +01:00
parent 33dd6d008b
commit c87a1b7f62
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 52 additions and 8 deletions

View File

@ -68,6 +68,8 @@ pub enum DebugEvent {
glyph_slots_total: u32,
sound_slots_used: u32,
sound_slots_total: u32,
scene_slots_used: u32,
scene_slots_total: u32,
},
#[serde(rename = "fault")]
Fault {
@ -99,6 +101,8 @@ mod tests {
glyph_slots_total: 16,
sound_slots_used: 2,
sound_slots_total: 16,
scene_slots_used: 3,
scene_slots_total: 16,
};
let json = serde_json::to_string(&event).unwrap();

View File

@ -1,8 +1,7 @@
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
pub(crate) const ENTRIES: &[SyscallRegistryEntry] =
&[SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
.args(1)
.rets(2)
.caps(caps::BANK),
];
.caps(caps::BANK)];

View File

@ -18,6 +18,8 @@ pub struct TelemetryFrame {
pub glyph_slots_total: u32,
pub sound_slots_used: u32,
pub sound_slots_total: u32,
pub scene_slots_used: u32,
pub scene_slots_total: u32,
// RAM (Heap)
pub heap_used_bytes: usize,
@ -45,6 +47,8 @@ pub struct AtomicTelemetry {
pub glyph_slots_total: AtomicU32,
pub sound_slots_used: AtomicU32,
pub sound_slots_total: AtomicU32,
pub scene_slots_used: AtomicU32,
pub scene_slots_total: AtomicU32,
// RAM (Heap)
pub heap_used_bytes: AtomicUsize,
@ -75,6 +79,8 @@ impl AtomicTelemetry {
glyph_slots_total: self.glyph_slots_total.load(Ordering::Relaxed),
sound_slots_used: self.sound_slots_used.load(Ordering::Relaxed),
sound_slots_total: self.sound_slots_total.load(Ordering::Relaxed),
scene_slots_used: self.scene_slots_used.load(Ordering::Relaxed),
scene_slots_total: self.scene_slots_total.load(Ordering::Relaxed),
heap_used_bytes: self.heap_used_bytes.load(Ordering::Relaxed),
heap_max_bytes: self.heap_max_bytes.load(Ordering::Relaxed),
logs_count: self.logs_count.load(Ordering::Relaxed),
@ -93,6 +99,8 @@ impl AtomicTelemetry {
self.glyph_slots_total.store(0, Ordering::Relaxed);
self.sound_slots_used.store(0, Ordering::Relaxed);
self.sound_slots_total.store(0, Ordering::Relaxed);
self.scene_slots_used.store(0, Ordering::Relaxed);
self.scene_slots_total.store(0, Ordering::Relaxed);
self.heap_used_bytes.store(0, Ordering::Relaxed);
self.vm_steps.store(0, Ordering::Relaxed);
self.logs_count.store(0, Ordering::Relaxed);

View File

@ -7,7 +7,9 @@ use prometeu_vm::LogicalFrameEndingReason;
use std::sync::atomic::Ordering;
impl VirtualMachineRuntime {
fn bank_telemetry_summary(hw: &dyn HardwareBridge) -> (BankTelemetry, BankTelemetry) {
fn bank_telemetry_summary(
hw: &dyn HardwareBridge,
) -> (BankTelemetry, BankTelemetry, BankTelemetry) {
let telemetry = hw.assets().bank_telemetry();
let glyph =
telemetry.iter().find(|entry| entry.bank_type == BankType::GLYPH).cloned().unwrap_or(
@ -17,8 +19,12 @@ impl VirtualMachineRuntime {
telemetry.iter().find(|entry| entry.bank_type == BankType::SOUNDS).cloned().unwrap_or(
BankTelemetry { bank_type: BankType::SOUNDS, used_slots: 0, total_slots: 0 },
);
let scenes =
telemetry.iter().find(|entry| entry.bank_type == BankType::SCENE).cloned().unwrap_or(
BankTelemetry { bank_type: BankType::SCENE, used_slots: 0, total_slots: 0 },
);
(glyph, sounds)
(glyph, sounds, scenes)
}
pub fn debug_step_instruction(
@ -148,7 +154,7 @@ impl VirtualMachineRuntime {
hw.render_frame();
// 1. Snapshot full telemetry at logical frame end
let (glyph_bank, sound_bank) = Self::bank_telemetry_summary(hw);
let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(hw);
self.atomic_telemetry
.glyph_slots_used
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
@ -161,6 +167,12 @@ impl VirtualMachineRuntime {
self.atomic_telemetry
.sound_slots_total
.store(sound_bank.total_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.scene_slots_used
.store(scene_bank.used_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.scene_slots_total
.store(scene_bank.total_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.heap_used_bytes
@ -218,7 +230,7 @@ impl VirtualMachineRuntime {
// 2. High-frequency telemetry update (only if inspection is active)
if self.inspection_active {
let (glyph_bank, sound_bank) = Self::bank_telemetry_summary(hw);
let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(hw);
self.atomic_telemetry
.glyph_slots_used
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
@ -231,6 +243,12 @@ impl VirtualMachineRuntime {
self.atomic_telemetry
.sound_slots_total
.store(sound_bank.total_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.scene_slots_used
.store(scene_bank.used_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.scene_slots_total
.store(scene_bank.total_slots as u32, Ordering::Relaxed);
self.atomic_telemetry
.heap_used_bytes

View File

@ -294,6 +294,8 @@ impl HostDebugger {
glyph_slots_total: telemetry.glyph_slots_total,
sound_slots_used: telemetry.sound_slots_used,
sound_slots_total: telemetry.sound_slots_total,
scene_slots_used: telemetry.scene_slots_used,
scene_slots_total: telemetry.scene_slots_total,
}
}

View File

@ -94,6 +94,7 @@ pub(crate) fn capture_snapshot(stats: &HostStats, firmware: &Firmware) -> Overla
let heap_ratio = ratio(tel.heap_used_bytes as u64, heap_total_bytes as u64);
let glyph_ratio = ratio(tel.glyph_slots_used as u64, tel.glyph_slots_total as u64);
let sound_ratio = ratio(tel.sound_slots_used as u64, tel.sound_slots_total as u64);
let scene_ratio = ratio(tel.scene_slots_used as u64, tel.scene_slots_total as u64);
OverlaySnapshot {
rows: vec![
@ -163,6 +164,12 @@ pub(crate) fn capture_snapshot(stats: &HostStats, firmware: &Firmware) -> Overla
ratio: sound_ratio,
warn: tel.sound_slots_total > 0 && tel.sound_slots_used >= tel.sound_slots_total,
},
OverlayBar {
label: "SCENE",
value: format!("{} / {} slots", tel.scene_slots_used, tel.scene_slots_total),
ratio: scene_ratio,
warn: tel.scene_slots_total > 0 && tel.scene_slots_used >= tel.scene_slots_total,
},
],
footer,
}

View File

@ -387,6 +387,8 @@ mod tests {
glyph_slots_total: 16,
sound_slots_used: 0,
sound_slots_total: 8,
scene_slots_used: 2,
scene_slots_total: 16,
..Default::default()
};
@ -403,6 +405,8 @@ mod tests {
glyph_slots_total,
sound_slots_used,
sound_slots_total,
scene_slots_used,
scene_slots_total,
} => {
assert_eq!(frame_index, 8);
assert_eq!(vm_steps, 123);
@ -415,6 +419,8 @@ mod tests {
assert_eq!(glyph_slots_total, 16);
assert_eq!(sound_slots_used, 0);
assert_eq!(sound_slots_total, 8);
assert_eq!(scene_slots_used, 2);
assert_eq!(scene_slots_total, 16);
}
other => panic!("unexpected telemetry event: {:?}", other),
}