fixed a deadlock

This commit is contained in:
2025-06-15 16:51:20 +01:00
parent aca73589de
commit 5d1ea86cdd
5 changed files with 49 additions and 29 deletions
+27 -17
View File
@@ -1,6 +1,6 @@
use std::{
sync::{
Arc, Mutex,
Arc, Mutex, MutexGuard,
mpsc::{self, Receiver, Sender},
},
thread,
@@ -15,27 +15,39 @@ use crate::{
},
};
pub fn run_emulator(
cmd_rx: &Receiver<Command>,
state_tx: &Sender<State>,
cpu: &Arc<Mutex<Processor>>,
) {
pub fn run_emulator(cmd_rx: &Receiver<Command>, state_tx: &Sender<State>, cpu: Processor) {
println!("starting");
let mut running = Running::Paused;
let mut addr = 0u32;
let size = 256;
// Send initial state.
let Ok(mut cpu_lock) = cpu.lock() else {
panic!("Failed to lock CPU.")
};
// let Ok(mut cpu_lock) = cpu.lock() else {
// panic!("Failed to lock CPU.")
// };
let mut cpu_lock = cpu;
cpu_lock.get_stack(32);
println!("got stack");
cpu_lock.display();
println!("got display");
let memory_view = cpu_lock.memory.read_range(addr, size);
let initial_state = state(cpu, running, 0, memory_view);
println!("got view");
let initial_state = state(&mut cpu_lock, running, 0, memory_view);
println!("got state");
let _ = state_tx.send(initial_state);
println!("sent state");
let mut instruction_count = 0;
loop {
println!("looping");
let cmd = if running == Running::Running {
match cmd_rx.try_recv() {
Ok(cmd) => Some(cmd),
@@ -50,6 +62,8 @@ pub fn run_emulator(
};
if let Some(cmd) = cmd {
println!("Received command: {:?}", cmd);
match cmd {
Command::Start => {
running = Running::Running;
@@ -95,7 +109,7 @@ pub fn run_emulator(
}
let memory_view = cpu_lock.memory.read_range(addr, size);
let state = state(cpu, running, instruction_count, memory_view);
let state = state(&mut cpu_lock, running, instruction_count, memory_view);
let _ = state_tx.send(state);
}
@@ -129,7 +143,7 @@ pub fn run_emulator(
if update {
let memory_view = cpu_lock.memory.read_range(addr, size);
let state = state(cpu, running, instruction_count, memory_view);
let state = state(&mut cpu_lock, running, instruction_count, memory_view);
let _ = state_tx.send(state);
}
} else {
@@ -139,15 +153,11 @@ pub fn run_emulator(
}
fn state(
cpu: &Arc<Mutex<Processor>>,
cpu_lock: &mut Processor,
running: Running,
instruction_count: usize,
memory_view: Vec<u8>,
) -> State {
let Ok(mut cpu_lock) = cpu.lock() else {
panic!("Could not lock CPU.")
};
State {
// TODO: Replace with actual register access from your CPU.
reg_file: cpu_lock.registers,
+8
View File
@@ -7,6 +7,14 @@ pub enum Running {
Halted,
}
pub trait IODevice: Send + Sync {
fn read_byte(&mut self, addr: u32) -> u8;
fn write_byte(&mut self, addr: u32, value: u8);
fn read_range(&mut self, addr: u32, size: u32) -> Vec<u8>;
fn write_range(&mut self, addr: u32, value: Vec<u8>);
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Command {
Start,
Stop,
+11 -5
View File
@@ -1,27 +1,33 @@
use std::cmp::{max, min};
use std::{
cmp::{max, min},
sync::Arc,
};
use crate::{
common::instructions::{Instruction, Interrupt, Register, errors::InstructionDecodeError},
emulator::system::{memory::MemoryUnit, model::RegFile},
emulator::system::{
memory::MemoryUnit,
model::{IODevice, RegFile},
},
};
pub struct Processor {
pub memory: Box<dyn MemoryUnit>,
pub registers: RegFile,
pub halted: bool,
// pub io_devices: Vec<Arc<dyn IODevice>>,
pub io_devices: Vec<Arc<dyn IODevice>>,
}
#[allow(clippy::needless_pass_by_ref_mut)]
impl Processor {
// io_devices: Vec<Arc<dyn IODevice>>
#[must_use]
pub fn new(memory: Box<dyn MemoryUnit>) -> Self {
pub fn new(memory: Box<dyn MemoryUnit>, io_devices: Vec<Arc<dyn IODevice>>) -> Self {
Self {
// io_devices,
memory,
registers: RegFile::default(),
halted: false,
io_devices,
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ use crate::{
fn create_test_processor() -> Processor {
let memory = Box::new(MainStore::new());
Processor::new(memory)
Processor::new(memory, Vec::new())
}
#[test]
+2 -6
View File
@@ -17,14 +17,10 @@ fn main() -> Result<(), eframe::Error> {
let (state_sender, state_receiver) = std::sync::mpsc::channel();
let mainstore = MainStore::new();
let processor = Processor::new(Box::new(mainstore));
let processor = Processor::new(Box::new(mainstore), vec![]);
thread::spawn(move || {
run_emulator(
&cmd_receiver,
&state_sender,
&Arc::new(Mutex::new(processor)),
);
run_emulator(&cmd_receiver, &state_sender, processor);
});
// Create UI