Start implementing profiling

This commit is contained in:
2025-08-27 22:49:44 -04:00
parent 6272f6cc21
commit 11c17cb246
5 changed files with 246 additions and 16 deletions
+50 -8
View File
@@ -18,7 +18,7 @@ use tracing::{error, warn};
use crate::{
audio::Audio,
emulator::cart::Cart,
emulator::{cart::Cart, profiler::Profiler},
graphics::TextureSink,
memory::{MemoryRange, MemoryRegion},
};
@@ -27,6 +27,7 @@ pub use shrooms_vb_core::{VBKey, VBRegister, VBWatchpointType};
mod address_set;
mod cart;
mod profiler;
mod shrooms_vb_core;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
@@ -69,6 +70,7 @@ pub struct EmulatorBuilder {
audio_on: Arc<[AtomicBool; 2]>,
linked: Arc<AtomicBool>,
start_paused: bool,
monitor_events: bool,
}
impl EmulatorBuilder {
@@ -85,6 +87,7 @@ impl EmulatorBuilder {
audio_on: Arc::new([AtomicBool::new(true), AtomicBool::new(true)]),
linked: Arc::new(AtomicBool::new(false)),
start_paused: false,
monitor_events: false,
};
let client = EmulatorClient {
queue,
@@ -110,6 +113,13 @@ impl EmulatorBuilder {
}
}
pub fn monitor_events(self, monitor_events: bool) -> Self {
Self {
monitor_events,
..self
}
}
pub fn build(self) -> Result<Emulator> {
let mut emulator = Emulator::new(
self.commands,
@@ -124,6 +134,9 @@ impl EmulatorBuilder {
if self.start_paused {
emulator.pause_sims()?;
}
if self.monitor_events {
emulator.monitor_events(SimId::Player1)?;
}
Ok(emulator)
}
}
@@ -137,6 +150,7 @@ pub struct Emulator {
state: Arc<Atomic<EmulatorState>>,
audio_on: Arc<[AtomicBool; 2]>,
linked: Arc<AtomicBool>,
profilers: [Profiler; 2],
renderers: HashMap<SimId, TextureSink>,
messages: HashMap<SimId, mpsc::Sender<Toast>>,
debuggers: HashMap<SimId, DebugInfo>,
@@ -164,6 +178,7 @@ impl Emulator {
state,
audio_on,
linked,
profilers: [Profiler::new(), Profiler::new()],
renderers: HashMap::new(),
messages: HashMap::new(),
debuggers: HashMap::new(),
@@ -213,6 +228,7 @@ impl Emulator {
}
let sim = &mut self.sims[index];
sim.reset();
sim.monitor_events(self.profilers[sim_id.to_index()].is_enabled());
if let Some(cart) = new_cart {
sim.load_cart(cart.rom.clone(), cart.sram.clone())?;
self.carts[index] = Some(cart);
@@ -383,6 +399,11 @@ impl Emulator {
self.watched_regions.insert(range, region);
}
fn monitor_events(&mut self, sim_id: SimId) -> Result<()> {
self.profilers[sim_id.to_index()].enable(true);
self.reset_sim(sim_id, None)
}
pub fn run(&mut self) {
loop {
let idle = self.tick();
@@ -438,12 +459,20 @@ impl Emulator {
let p1_running = running && p1_state == SimState::Ready;
let p2_running = running && p2_state == SimState::Ready;
let mut idle = !p1_running && !p2_running;
if p1_running && p2_running {
Sim::emulate_many(&mut self.sims);
} else if p1_running {
self.sims[SimId::Player1.to_index()].emulate();
} else if p2_running {
self.sims[SimId::Player2.to_index()].emulate();
let cycles = self.emulate(p1_running, p2_running);
// if we're profiling, track events
for ((sim, profiler), running) in self
.sims
.iter_mut()
.zip(self.profilers.iter_mut())
.zip([p1_running, p2_running])
{
if !running || !profiler.is_enabled() {
continue;
}
profiler.track(cycles, sim.take_sim_event());
}
if state == EmulatorState::Stepping {
@@ -470,7 +499,7 @@ impl Emulator {
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
continue;
};
if let Some(reason) = sim.stop_reason() {
if let Some(reason) = sim.take_stop_reason() {
let stop_reason = match reason {
StopReason::Stepped => DebugStopReason::Trace,
StopReason::Watchpoint(watch, address) => {
@@ -529,6 +558,19 @@ impl Emulator {
idle
}
fn emulate(&mut self, p1_running: bool, p2_running: bool) -> u32 {
const MAX_CYCLES: u32 = 20_000_000;
let mut cycles = MAX_CYCLES;
if p1_running && p2_running {
Sim::emulate_many(&mut self.sims, &mut cycles);
} else if p1_running {
self.sims[SimId::Player1.to_index()].emulate(&mut cycles);
} else if p2_running {
self.sims[SimId::Player2.to_index()].emulate(&mut cycles);
}
MAX_CYCLES - cycles
}
fn handle_command(&mut self, command: EmulatorCommand) {
match command {
EmulatorCommand::ConnectToSim(sim_id, renderer, messages) => {