diff --git a/src/runtime2/component/component_ip.rs b/src/runtime2/component/component_ip.rs index a3a83aa59df50bf6bb336fd7cbd53aaaf66551b8..87c65d3baa7173c5dabd768677bd9cea5cce17ba 100644 --- a/src/runtime2/component/component_ip.rs +++ b/src/runtime2/component/component_ip.rs @@ -1,14 +1,21 @@ -use crate::protocol::eval::*; +use crate::protocol::eval::{ValueGroup, EvalError}; use crate::runtime2::*; use super::*; -use super::component::*; +use super::component::{self, Component, CompExecState, CompScheduling, CompMode}; +use super::control_layer::*; +use super::consensus::*; /// TODO: Temporary component to figure out what to do with custom components. /// This component sends random numbers between two u32 limits pub struct ComponentRandomU32 { + // Properties for this specific component output_port_id: PortId, random_minimum: u32, random_maximum: u32, + // Generic state-tracking + exec_state: CompExecState, + control: ControlLayer, + consensus: Consensus, } impl Component for ComponentRandomU32 { @@ -20,18 +27,46 @@ impl Component for ComponentRandomU32 { fn handle_message(&mut self, sched_ctx: &mut SchedulerCtx, comp_ctx: &mut CompCtx, message: Message) { match message { - Message::Data(message) => unreachable!(), + Message::Data(_message) => unreachable!(), Message::Sync(message) => { - + let decision = self.consensus.receive_sync_message(sched_ctx, comp_ctx, message); + self.handle_sync_decision(sched_ctx, comp_ctx, decision); }, Message::Control(message) => { - + component::default_handle_control_message( + &mut self.exec_state, &mut self.control, &mut self.consensus, + message, sched_ctx, comp_ctx + ); } } } fn run(&mut self, sched_ctx: &mut SchedulerCtx, comp_ctx: &mut CompCtx) -> Result { - todo!() + sched_ctx.log(&format!("Running component ComponentRandomU32 (mode: {:?})", self.exec_state.mode)); + + match self.exec_state.mode { + CompMode::BlockedGet | CompMode::BlockedSelect => { + // impossible for this component, no input ports and no select + // blocks + unreachable!(); + } + CompMode::NonSync => { + // If in non-sync mode then we check if the arguments make sense + // (at some point in the future, this is just a testing + // component) + }, + CompMode::Sync => { + + }, + CompMode::SyncEnd | CompMode::BlockedPut => return Ok(CompScheduling::Sleep), + CompMode::StartExit => return Ok(component::default_handle_start_exit( + &mut self.exec_state, &mut self.control, sched_ctx, comp_ctx + )), + CompMode::BusyExit => return Ok(component::default_handle_busy_exit( + &mut self.exec_state, &self.control, sched_ctx + )), + CompMode::Exit => return Ok(component::default_handle_exit(&self.exec_state)), + } } } @@ -39,7 +74,7 @@ impl ComponentRandomU32 { pub(crate) fn new(arguments: ValueGroup) -> Self { debug_assert_eq!(arguments.values.len(), 3); debug_assert!(arguments.regions.is_empty()); - let port_id = port_id_from_eval(arguments.values[0].as_port_id()); + let port_id = component::port_id_from_eval(arguments.values[0].as_port_id()); let minimum = arguments.values[1].as_uint32(); let maximum = arguments.values[2].as_uint32(); @@ -47,6 +82,27 @@ impl ComponentRandomU32 { output_port_id: port_id, random_minimum: minimum, random_maximum: maximum, + exec_state: CompExecState::new(), + control: ControlLayer::default(), + consensus: Consensus::new(), + } + } + + + + fn handle_sync_decision(&mut self, _sched_ctx: &SchedulerCtx, _comp_ctx: &mut CompCtx, decision: SyncRoundDecision) { + let success = match decision { + SyncRoundDecision::None => return, + SyncRoundDecision::Solution => true, + SyncRoundDecision::Failure => false, + }; + + debug_assert_eq!(self.exec_state.mode, CompMode::SyncEnd); + if success { + self.exec_state.mode = CompMode::NonSync; + self.consensus.notify_sync_decision(decision); + } else { + self.exec_state.mode = CompMode::StartExit; } } } \ No newline at end of file