diff options
-rw-r--r-- | src/simulator.rs | 39 | ||||
-rw-r--r-- | src/syscall.rs | 4 |
2 files changed, 29 insertions, 14 deletions
diff --git a/src/simulator.rs b/src/simulator.rs index 41331ef..8e2a0a5 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -33,6 +33,16 @@ pub struct Core<'a> { stall_count: u32, } +/// Why the simulator has halted execution. +pub enum HaltReason { + /// All cores have halted execution. + CoresHalted, + /// The simulator has hit the cycle limit. + OutOfCycles, + /// The syscall handler has requested a halt. + SystemHalt, +} + pub struct Simulator<'a, T: SyscallHandler> { cores: Vec<Core<'a>>, memory: SharedMemory<'a>, @@ -410,32 +420,33 @@ impl<'a, T: SyscallHandler> Simulator<'a, T> { ran } - fn report(&self) { - for core in self.cores.iter() { - println!("Core {}: stalled {} of {}", - core.id, core.stall_count, core.cycle_count); - } + pub fn report(&self) -> Vec<(usize, u32, u32)> { + self.cores.iter() + .map(|core| (core.id, core.stall_count, core.cycle_count)) + .collect() } - pub fn run(&mut self) { + pub fn run(&mut self) -> HaltReason { loop { if !self.step() { - break + return HaltReason::CoresHalted; + } + if self.syscall.should_halt() { + return HaltReason::SystemHalt; } } - - println!("All cores are not running, stopping..."); - self.report(); } - pub fn run_max(&mut self, cycles: usize) { + pub fn run_max(&mut self, cycles: usize) -> HaltReason { for _ in 0..cycles { if !self.step() { - break + return HaltReason::CoresHalted; + } + if self.syscall.should_halt() { + return HaltReason::SystemHalt; } } - println!("Out of cycles, stopping..."); - self.report(); + return HaltReason::OutOfCycles; } } diff --git a/src/syscall.rs b/src/syscall.rs index 6da9e47..01cc8f0 100644 --- a/src/syscall.rs +++ b/src/syscall.rs @@ -20,6 +20,10 @@ use trap; pub trait SyscallHandler { // Can't take cache because syscall can't stall + /// Implement the syscall requested by core_id. fn syscall(&mut self, core_id: usize, registers: &mut RegisterFile, mmu: &Mmu) -> Option<trap::Trap>; + + /// Determine, after each cycle, whether the processor should halt. + fn should_halt(&self) -> bool; } |