dev/perf-runtime-introspection-syscalls #17
@ -68,6 +68,8 @@ pub enum DebugEvent {
|
|||||||
glyph_slots_total: u32,
|
glyph_slots_total: u32,
|
||||||
sound_slots_used: u32,
|
sound_slots_used: u32,
|
||||||
sound_slots_total: u32,
|
sound_slots_total: u32,
|
||||||
|
scene_slots_used: u32,
|
||||||
|
scene_slots_total: u32,
|
||||||
},
|
},
|
||||||
#[serde(rename = "fault")]
|
#[serde(rename = "fault")]
|
||||||
Fault {
|
Fault {
|
||||||
@ -99,6 +101,8 @@ mod tests {
|
|||||||
glyph_slots_total: 16,
|
glyph_slots_total: 16,
|
||||||
sound_slots_used: 2,
|
sound_slots_used: 2,
|
||||||
sound_slots_total: 16,
|
sound_slots_total: 16,
|
||||||
|
scene_slots_used: 3,
|
||||||
|
scene_slots_total: 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string(&event).unwrap();
|
let json = serde_json::to_string(&event).unwrap();
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
|
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
|
||||||
|
|
||||||
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
pub(crate) const ENTRIES: &[SyscallRegistryEntry] =
|
||||||
SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
|
&[SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
|
||||||
.args(1)
|
.args(1)
|
||||||
.rets(2)
|
.rets(2)
|
||||||
.caps(caps::BANK),
|
.caps(caps::BANK)];
|
||||||
];
|
|
||||||
|
|||||||
@ -18,6 +18,8 @@ pub struct TelemetryFrame {
|
|||||||
pub glyph_slots_total: u32,
|
pub glyph_slots_total: u32,
|
||||||
pub sound_slots_used: u32,
|
pub sound_slots_used: u32,
|
||||||
pub sound_slots_total: u32,
|
pub sound_slots_total: u32,
|
||||||
|
pub scene_slots_used: u32,
|
||||||
|
pub scene_slots_total: u32,
|
||||||
|
|
||||||
// RAM (Heap)
|
// RAM (Heap)
|
||||||
pub heap_used_bytes: usize,
|
pub heap_used_bytes: usize,
|
||||||
@ -45,6 +47,8 @@ pub struct AtomicTelemetry {
|
|||||||
pub glyph_slots_total: AtomicU32,
|
pub glyph_slots_total: AtomicU32,
|
||||||
pub sound_slots_used: AtomicU32,
|
pub sound_slots_used: AtomicU32,
|
||||||
pub sound_slots_total: AtomicU32,
|
pub sound_slots_total: AtomicU32,
|
||||||
|
pub scene_slots_used: AtomicU32,
|
||||||
|
pub scene_slots_total: AtomicU32,
|
||||||
|
|
||||||
// RAM (Heap)
|
// RAM (Heap)
|
||||||
pub heap_used_bytes: AtomicUsize,
|
pub heap_used_bytes: AtomicUsize,
|
||||||
@ -75,6 +79,8 @@ impl AtomicTelemetry {
|
|||||||
glyph_slots_total: self.glyph_slots_total.load(Ordering::Relaxed),
|
glyph_slots_total: self.glyph_slots_total.load(Ordering::Relaxed),
|
||||||
sound_slots_used: self.sound_slots_used.load(Ordering::Relaxed),
|
sound_slots_used: self.sound_slots_used.load(Ordering::Relaxed),
|
||||||
sound_slots_total: self.sound_slots_total.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_used_bytes: self.heap_used_bytes.load(Ordering::Relaxed),
|
||||||
heap_max_bytes: self.heap_max_bytes.load(Ordering::Relaxed),
|
heap_max_bytes: self.heap_max_bytes.load(Ordering::Relaxed),
|
||||||
logs_count: self.logs_count.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.glyph_slots_total.store(0, Ordering::Relaxed);
|
||||||
self.sound_slots_used.store(0, Ordering::Relaxed);
|
self.sound_slots_used.store(0, Ordering::Relaxed);
|
||||||
self.sound_slots_total.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.heap_used_bytes.store(0, Ordering::Relaxed);
|
||||||
self.vm_steps.store(0, Ordering::Relaxed);
|
self.vm_steps.store(0, Ordering::Relaxed);
|
||||||
self.logs_count.store(0, Ordering::Relaxed);
|
self.logs_count.store(0, Ordering::Relaxed);
|
||||||
|
|||||||
@ -7,7 +7,9 @@ use prometeu_vm::LogicalFrameEndingReason;
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
impl VirtualMachineRuntime {
|
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 telemetry = hw.assets().bank_telemetry();
|
||||||
let glyph =
|
let glyph =
|
||||||
telemetry.iter().find(|entry| entry.bank_type == BankType::GLYPH).cloned().unwrap_or(
|
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(
|
telemetry.iter().find(|entry| entry.bank_type == BankType::SOUNDS).cloned().unwrap_or(
|
||||||
BankTelemetry { bank_type: BankType::SOUNDS, used_slots: 0, total_slots: 0 },
|
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(
|
pub fn debug_step_instruction(
|
||||||
@ -148,7 +154,7 @@ impl VirtualMachineRuntime {
|
|||||||
hw.render_frame();
|
hw.render_frame();
|
||||||
|
|
||||||
// 1. Snapshot full telemetry at logical frame end
|
// 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
|
self.atomic_telemetry
|
||||||
.glyph_slots_used
|
.glyph_slots_used
|
||||||
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
||||||
@ -161,6 +167,12 @@ impl VirtualMachineRuntime {
|
|||||||
self.atomic_telemetry
|
self.atomic_telemetry
|
||||||
.sound_slots_total
|
.sound_slots_total
|
||||||
.store(sound_bank.total_slots as u32, Ordering::Relaxed);
|
.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
|
self.atomic_telemetry
|
||||||
.heap_used_bytes
|
.heap_used_bytes
|
||||||
@ -218,7 +230,7 @@ impl VirtualMachineRuntime {
|
|||||||
|
|
||||||
// 2. High-frequency telemetry update (only if inspection is active)
|
// 2. High-frequency telemetry update (only if inspection is active)
|
||||||
if self.inspection_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
|
self.atomic_telemetry
|
||||||
.glyph_slots_used
|
.glyph_slots_used
|
||||||
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
.store(glyph_bank.used_slots as u32, Ordering::Relaxed);
|
||||||
@ -231,6 +243,12 @@ impl VirtualMachineRuntime {
|
|||||||
self.atomic_telemetry
|
self.atomic_telemetry
|
||||||
.sound_slots_total
|
.sound_slots_total
|
||||||
.store(sound_bank.total_slots as u32, Ordering::Relaxed);
|
.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
|
self.atomic_telemetry
|
||||||
.heap_used_bytes
|
.heap_used_bytes
|
||||||
|
|||||||
@ -294,6 +294,8 @@ impl HostDebugger {
|
|||||||
glyph_slots_total: telemetry.glyph_slots_total,
|
glyph_slots_total: telemetry.glyph_slots_total,
|
||||||
sound_slots_used: telemetry.sound_slots_used,
|
sound_slots_used: telemetry.sound_slots_used,
|
||||||
sound_slots_total: telemetry.sound_slots_total,
|
sound_slots_total: telemetry.sound_slots_total,
|
||||||
|
scene_slots_used: telemetry.scene_slots_used,
|
||||||
|
scene_slots_total: telemetry.scene_slots_total,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 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 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 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 {
|
OverlaySnapshot {
|
||||||
rows: vec![
|
rows: vec![
|
||||||
@ -163,6 +164,12 @@ pub(crate) fn capture_snapshot(stats: &HostStats, firmware: &Firmware) -> Overla
|
|||||||
ratio: sound_ratio,
|
ratio: sound_ratio,
|
||||||
warn: tel.sound_slots_total > 0 && tel.sound_slots_used >= tel.sound_slots_total,
|
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,
|
footer,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -387,6 +387,8 @@ mod tests {
|
|||||||
glyph_slots_total: 16,
|
glyph_slots_total: 16,
|
||||||
sound_slots_used: 0,
|
sound_slots_used: 0,
|
||||||
sound_slots_total: 8,
|
sound_slots_total: 8,
|
||||||
|
scene_slots_used: 2,
|
||||||
|
scene_slots_total: 16,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -403,6 +405,8 @@ mod tests {
|
|||||||
glyph_slots_total,
|
glyph_slots_total,
|
||||||
sound_slots_used,
|
sound_slots_used,
|
||||||
sound_slots_total,
|
sound_slots_total,
|
||||||
|
scene_slots_used,
|
||||||
|
scene_slots_total,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!(frame_index, 8);
|
assert_eq!(frame_index, 8);
|
||||||
assert_eq!(vm_steps, 123);
|
assert_eq!(vm_steps, 123);
|
||||||
@ -415,6 +419,8 @@ mod tests {
|
|||||||
assert_eq!(glyph_slots_total, 16);
|
assert_eq!(glyph_slots_total, 16);
|
||||||
assert_eq!(sound_slots_used, 0);
|
assert_eq!(sound_slots_used, 0);
|
||||||
assert_eq!(sound_slots_total, 8);
|
assert_eq!(sound_slots_total, 8);
|
||||||
|
assert_eq!(scene_slots_used, 2);
|
||||||
|
assert_eq!(scene_slots_total, 16);
|
||||||
}
|
}
|
||||||
other => panic!("unexpected telemetry event: {:?}", other),
|
other => panic!("unexpected telemetry event: {:?}", other),
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user