feat: migrate to parking_lot mutex and add system control architecture

This commit is contained in:
Jan-Peter von Hunnius 2026-02-28 18:27:27 +01:00
parent 14060e15e5
commit 54144d10e9
29 changed files with 2387 additions and 1130 deletions

View file

@ -5,7 +5,8 @@
//! to emulator state for real-time GUI updates.
use crate::system_config::ConfigurableSystem;
use std::sync::{Arc, Mutex};
use parking_lot::Mutex;
use std::sync::Arc;
/// GUI state structure containing all UI-relevant data
#[derive(Debug, Clone)]
@ -122,61 +123,55 @@ impl GuiState {
/// Update state from the current system
pub fn update_from_system(&mut self, system: &Arc<Mutex<ConfigurableSystem>>) {
if let Ok(system_guard) = system.lock() {
// Update basic system state
self.system_running = system_guard.is_running();
let system_guard = system.lock();
// Update basic system state
self.system_running = system_guard.is_running();
// Update system info if not already set
if self.system_info.is_none() {
self.system_info = Some(system_guard.get_system_info().into());
}
// Update system info if not already set
if self.system_info.is_none() {
self.system_info = Some(system_guard.get_system_info().into());
}
// Update component states
self.update_component_states(&system_guard);
// Update component states
self.update_component_states(&system_guard);
// Update CPU register state from real data
self.update_register_state(&system_guard);
// Update CPU register state from real data
self.update_register_state(&system_guard);
// Update RAM state from real data
self.update_ram_state(&system_guard);
// Update RAM state from real data
self.update_ram_state(&system_guard);
// Update ROM state from real data
self.update_rom_state(&system_guard);
// Update ROM state from real data
self.update_rom_state(&system_guard);
// Update cycle count (simulate for now)
if self.system_running {
self.cycle_count += 1;
}
// Update cycle count (simulate for now)
if self.system_running {
self.cycle_count += 1;
}
}
/// Update component running states
/// Uses try_lock() to avoid potential deadlocks when multiple threads
/// access components in different orders
/// Uses blocking locks for consistent GUI data - GUI can wait for simulation
fn update_component_states(&mut self, system: &ConfigurableSystem) {
let components = system.get_components();
// Use try_lock() to avoid blocking - if we can't get the lock immediately,
// just assume the component is not running (safe default for GUI display)
self.component_states.cpu_running = components.get("CPU_4004").map_or(false, |comp| {
comp.try_lock().map_or(false, |c| c.is_running())
});
// Use blocking locks for consistent data - GUI can wait for simulation
self.component_states.cpu_running = components
.get("CPU_4004")
.map_or(false, |comp| comp.lock().is_running());
self.component_states.ram_running = components.get("RAM_4002").map_or(false, |comp| {
comp.try_lock().map_or(false, |c| c.is_running())
});
self.component_states.ram_running = components
.get("RAM_4002")
.map_or(false, |comp| comp.lock().is_running());
self.component_states.rom_running = components
.get("ROM_4001_1")
.or_else(|| components.get("ROM_4001_2"))
.map_or(false, |comp| {
comp.try_lock().map_or(false, |c| c.is_running())
});
.map_or(false, |comp| comp.lock().is_running());
self.component_states.clock_running =
components.get("SYSTEM_CLOCK").map_or(false, |comp| {
comp.try_lock().map_or(false, |c| c.is_running())
});
self.component_states.clock_running = components
.get("SYSTEM_CLOCK")
.map_or(false, |comp| comp.lock().is_running());
}
/// Update CPU register state from real component data