diff options
author | Oxore <oxore@protonmail.com> | 2020-02-24 20:29:32 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2020-02-24 20:29:32 +0300 |
commit | f92e5bce166cc9f73e0fac40c5195745c763eba5 (patch) | |
tree | 834094605c77983f7da7c99af1a90a43765c0ae1 | |
parent | 730499e00555eddcbae653bee46f82e1f1d8a06f (diff) |
Use channel for comm-s between Core and Controller
-rw-r--r-- | src/main.rs | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs index 9ae0bae..74aeed0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,40 +3,69 @@ extern crate clap; use std::fs; use std::io; use std::io::prelude::*; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread::sleep; -use std::{thread, time}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread; +use std::time::Duration; mod core; mod rom; use self::core::Core; -fn cli_controller(asyncpair: Arc<(Mutex<bool>, Condvar)>) { - let &(ref should_stop, ref cvar) = &*asyncpair; +enum Control { + Run(bool), +} + +enum SimData {} + +struct BoundController { + tx: Sender<Control>, + _rx: Receiver<SimData>, +} + +struct BoundCore { + _tx: Sender<SimData>, + rx: Receiver<Control>, +} + +fn new_bound_pair() -> (BoundCore, BoundController) { + let (tx_c, rx_c): (Sender<Control>, Receiver<Control>) = channel(); + let (tx_d, rx_d): (Sender<SimData>, Receiver<SimData>) = channel(); + return ( + BoundCore { + _tx: tx_d, + rx: rx_c, + }, + BoundController { + tx: tx_c, + _rx: rx_d, + }, + ); +} + +fn cli_controller(bound: BoundController) { let stdin = io::stdin(); for line in stdin.lock().lines() { let line = line.unwrap(); match line.as_ref() { "stop" => { println!("stop"); - *should_stop.lock().unwrap() = true; + bound.tx.send(Control::Run(false)).unwrap(); } "start" => { println!("start"); - *should_stop.lock().unwrap() = false; - cvar.notify_one(); + bound.tx.send(Control::Run(true)).unwrap(); } _ => (), } } } -fn ws_controller(asyncpair: Arc<(Mutex<bool>, Condvar)>) { +fn ws_controller(_bound: BoundController) { // TODO implement - println!("{:?}", asyncpair); + println!("AAA"); } -fn new_controller(name: &str) -> Result<&dyn Fn(Arc<(Mutex<bool>, Condvar)>), i32> { +fn new_controller(name: &str) -> Result<&dyn Fn(BoundController), i32> { match name { "cli" => Ok(&cli_controller), "ws" => Ok(&ws_controller), @@ -44,21 +73,30 @@ fn new_controller(name: &str) -> Result<&dyn Fn(Arc<(Mutex<bool>, Condvar)>), i3 } } -fn core_worker(mut core: Core, should_stop: &Mutex<bool>, cvar: &Condvar) { +fn core_worker(mut core: Core, bound: BoundCore) { + let mut should_stop = false; loop { - while !(*should_stop.lock().unwrap()) { + if should_stop == true { + if let Ok(msg) = bound.rx.recv() { + match msg { + Control::Run(run) => should_stop = !run, + } + } + } else { println!("0x{:08x}: {}", core.pc(), core.op()); core.step(); - sleep(time::Duration::from_millis(1000)); - } - - while *should_stop.lock().unwrap() { - let _ = cvar.wait(should_stop.lock().unwrap()).unwrap(); + if let Ok(msg) = bound.rx.recv_timeout(Duration::from_millis(1000)) { + match msg { + Control::Run(run) => should_stop = !run, + } + } } } } fn main() { + /* Parse args*/ + let cli_args_matches = clap::App::new("x51emu") .version("0.1.0") .author("oxore") @@ -87,6 +125,7 @@ fn main() { let filename = cli_args_matches .value_of("file") .expect("No file name provided"); + let controller = { let controller_type_name = cli_args_matches .value_of("interface") @@ -97,12 +136,11 @@ fn main() { )) }; + /* Read program and instantiate a simulator */ + let data = fs::read_to_string(filename).unwrap_or_else(|_| panic!("Unable to read file {}", filename)); - let asyncpair = Arc::new((Mutex::new(false), Condvar::new())); - let asyncpair2 = asyncpair.clone(); - let core = match Core::new_with_rom_from_hex(data) { Ok(value) => value, Err(err_string) => { @@ -111,10 +149,13 @@ fn main() { } }; + /* Run core worker and controller */ + + let (bound_core, bound_controller) = new_bound_pair(); + thread::spawn(move || { - let (ref should_stop, ref condvar) = *asyncpair2; - core_worker(core, should_stop, condvar); + core_worker(core, bound_core); }); - controller(asyncpair); + controller(bound_controller); } |