Files
@ 135965141596
Branch filter:
Location: CSY/reowolf/src/runtime2/component/component_ip.rs
135965141596
4.1 KiB
application/rls-services+xml
Factor out common component shutdown handling
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 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;
}
}
}
|