fixed a deadlock
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user