Files @ 135965141596
Branch filter:

Location: CSY/reowolf/src/runtime2/component/component_ip.rs

135965141596 4.1 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
mh
Factor out common component shutdown handling
use crate::protocol::eval::{ValueGroup, EvalError};
use crate::runtime2::*;
use super::*;
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 {
    fn adopt_message(&mut self, _comp_ctx: &mut CompCtx, _message: DataMessage) {
        // Impossible since this component does not have any input ports in its
        // signature.
        unreachable!();
    }

    fn handle_message(&mut self, sched_ctx: &mut SchedulerCtx, comp_ctx: &mut CompCtx, message: Message) {
        match message {
            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<CompScheduling, EvalError> {
        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)),
        }
    }
}

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 = 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();

        return Self{
            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;
        }
    }
}