[PERF] Host Debug Overlay Isolation
This commit is contained in:
parent
47ab664280
commit
b8d33c9e02
@ -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>,
|
||||
|
||||
@ -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)]
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user