dev/perf-host-debug-overlay-isolation #14

Merged
bquarkz merged 11 commits from dev/perf-host-debug-overlay-isolation into master 2026-04-10 22:20:40 +00:00
8 changed files with 83 additions and 29 deletions
Showing only changes of commit b8d33c9e02 - Show all commits

View File

@ -1,7 +1,7 @@
use crate::log::{LogEvent, LogLevel, LogSource};
use std::collections::VecDeque;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};
pub struct LogService {
events: VecDeque<LogEvent>,

View File

@ -1,6 +1,6 @@
use crate::log::{LogLevel, LogService, LogSource};
use std::sync::atomic::{AtomicU32, AtomicU64, AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, AtomicU64, AtomicUsize, Ordering};
#[derive(Debug, Clone, Copy, Default)]
pub struct TelemetryFrame {
@ -64,10 +64,7 @@ pub struct AtomicTelemetry {
impl AtomicTelemetry {
pub fn new(logs_count: Arc<AtomicU32>) -> Self {
Self {
logs_count,
..Default::default()
}
Self { logs_count, ..Default::default() }
}
/// Snapshots the current atomic state into a TelemetryFrame.
@ -92,6 +89,23 @@ impl AtomicTelemetry {
vm_steps: self.vm_steps.load(Ordering::Relaxed),
}
}
pub fn reset(&self) {
self.frame_index.store(0, Ordering::Relaxed);
self.cycles_used.store(0, Ordering::Relaxed);
self.syscalls.store(0, Ordering::Relaxed);
self.host_cpu_time_us.store(0, Ordering::Relaxed);
self.completed_logical_frames.store(0, Ordering::Relaxed);
self.violations.store(0, Ordering::Relaxed);
self.gfx_used_bytes.store(0, Ordering::Relaxed);
self.gfx_inflight_bytes.store(0, Ordering::Relaxed);
self.gfx_slots_occupied.store(0, Ordering::Relaxed);
self.audio_used_bytes.store(0, Ordering::Relaxed);
self.audio_inflight_bytes.store(0, Ordering::Relaxed);
self.audio_slots_occupied.store(0, Ordering::Relaxed);
self.heap_used_bytes.store(0, Ordering::Relaxed);
self.vm_steps.store(0, Ordering::Relaxed);
}
}
#[derive(Debug, Clone, Copy, Default)]

View File

@ -9,11 +9,11 @@ use prometeu_hal::log::{LogLevel, LogSource};
use prometeu_hal::sprite::Sprite;
use prometeu_hal::syscalls::Syscall;
use prometeu_hal::vm_fault::VmFault;
use std::sync::atomic::Ordering;
use prometeu_hal::{
AudioOpStatus, GfxOpStatus, HostContext, HostReturn, NativeInterface, SyscallId, expect_bool,
expect_int,
};
use std::sync::atomic::Ordering;
impl VirtualMachineRuntime {
fn syscall_log_write(&mut self, level_val: i64, tag: u16, msg: String) -> Result<(), VmFault> {

View File

@ -89,6 +89,7 @@ impl VirtualMachineRuntime {
self.logical_frame_active = false;
self.logical_frame_remaining_cycles = 0;
self.last_frame_cpu_time_us = 0;
self.atomic_telemetry.reset();
self.open_files.clear();
self.next_handle = 1;

View File

@ -16,6 +16,7 @@ use prometeu_hal::glyph_bank::GLYPH_BANK_PALETTE_COUNT_V1;
use prometeu_hal::syscalls::caps;
use prometeu_vm::VmInitError;
use std::collections::HashMap;
use std::sync::atomic::Ordering;
#[derive(Default)]
struct MemFsBackend {

View File

@ -135,17 +135,33 @@ impl VirtualMachineRuntime {
// 1. Snapshot full telemetry at logical frame end
let gfx_stats = hw.assets().bank_info(BankType::GLYPH);
self.atomic_telemetry.gfx_used_bytes.store(gfx_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry.gfx_inflight_bytes.store(gfx_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry.gfx_slots_occupied.store(gfx_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry
.gfx_used_bytes
.store(gfx_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry
.gfx_inflight_bytes
.store(gfx_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry
.gfx_slots_occupied
.store(gfx_stats.slots_occupied as u32, Ordering::Relaxed);
let audio_stats = hw.assets().bank_info(BankType::SOUNDS);
self.atomic_telemetry.audio_used_bytes.store(audio_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry.audio_inflight_bytes.store(audio_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry.audio_slots_occupied.store(audio_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry
.audio_used_bytes
.store(audio_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry
.audio_inflight_bytes
.store(audio_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry
.audio_slots_occupied
.store(audio_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry.heap_used_bytes.store(vm.heap().used_bytes.load(Ordering::Relaxed), Ordering::Relaxed);
self.atomic_telemetry.host_cpu_time_us.store(start.elapsed().as_micros() as u64, Ordering::Relaxed);
self.atomic_telemetry
.heap_used_bytes
.store(vm.heap().used_bytes.load(Ordering::Relaxed), Ordering::Relaxed);
self.atomic_telemetry
.host_cpu_time_us
.store(start.elapsed().as_micros() as u64, Ordering::Relaxed);
let ts_ms = self.boot_time.elapsed().as_millis() as u64;
let telemetry_snapshot = self.atomic_telemetry.snapshot();
@ -157,7 +173,9 @@ impl VirtualMachineRuntime {
) as u32;
self.atomic_telemetry.violations.store(violations, Ordering::Relaxed);
self.atomic_telemetry.completed_logical_frames.fetch_add(1, Ordering::Relaxed);
self.atomic_telemetry
.completed_logical_frames
.fetch_add(1, Ordering::Relaxed);
self.log_service.reset_count();
@ -190,18 +208,30 @@ impl VirtualMachineRuntime {
if self.inspection_active {
let gfx_stats = hw.assets().bank_info(BankType::GLYPH);
self.atomic_telemetry.gfx_used_bytes.store(gfx_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry.gfx_inflight_bytes.store(gfx_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry.gfx_slots_occupied.store(gfx_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry
.gfx_inflight_bytes
.store(gfx_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry
.gfx_slots_occupied
.store(gfx_stats.slots_occupied as u32, Ordering::Relaxed);
let audio_stats = hw.assets().bank_info(BankType::SOUNDS);
self.atomic_telemetry.audio_used_bytes.store(audio_stats.used_bytes, Ordering::Relaxed);
self.atomic_telemetry.audio_inflight_bytes.store(audio_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry.audio_slots_occupied.store(audio_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry
.audio_inflight_bytes
.store(audio_stats.inflight_bytes, Ordering::Relaxed);
self.atomic_telemetry
.audio_slots_occupied
.store(audio_stats.slots_occupied as u32, Ordering::Relaxed);
self.atomic_telemetry.heap_used_bytes.store(vm.heap().used_bytes.load(Ordering::Relaxed), Ordering::Relaxed);
self.atomic_telemetry
.heap_used_bytes
.store(vm.heap().used_bytes.load(Ordering::Relaxed), Ordering::Relaxed);
self.atomic_telemetry.frame_index.store(self.logical_frame_index, Ordering::Relaxed);
self.atomic_telemetry.host_cpu_time_us.store(start.elapsed().as_micros() as u64, Ordering::Relaxed);
self.atomic_telemetry
.host_cpu_time_us
.store(start.elapsed().as_micros() as u64, Ordering::Relaxed);
}
None

View File

@ -198,15 +198,19 @@ impl HostRunner {
// Snapshot does not include violations, as they are part of certification (logical end of frame)
// But for visual debug, we can check if there are recent CA tags in logs
let recent_logs = self.firmware.os.log_service.get_recent(10);
let violations_count = recent_logs.iter().filter(|e| e.tag >= 0xCA01 && e.tag <= 0xCA07).count();
let violations_count =
recent_logs.iter().filter(|e| e.tag >= 0xCA01 && e.tag <= 0xCA07).count();
let cert_color = if violations_count > 0 { color_warn } else { color_text };
self.hardware.gfx.draw_text(10, 98, &format!("CERT RECENT: {}", violations_count), cert_color);
self.hardware.gfx.draw_text(
10,
98,
&format!("CERT RECENT: {}", violations_count),
cert_color,
);
if violations_count > 0
&& let Some(event) = recent_logs
.into_iter()
.rev()
.find(|e| e.tag >= 0xCA01 && e.tag <= 0xCA07)
&& let Some(event) =
recent_logs.into_iter().rev().find(|e| e.tag >= 0xCA01 && e.tag <= 0xCA07)
{
let mut msg = event.msg.clone();
if msg.len() > 30 {

View File

@ -68,7 +68,11 @@ impl HostStats {
cpu_load_audio,
firmware.os.tick_index,
firmware.os.logical_frame_index,
firmware.os.atomic_telemetry.completed_logical_frames.load(std::sync::atomic::Ordering::Relaxed),
firmware
.os
.atomic_telemetry
.completed_logical_frames
.load(std::sync::atomic::Ordering::Relaxed),
);
window.set_title(&title);
}