diff --git a/src/runtime2/runtime.rs b/src/runtime2/runtime.rs index 24844a612a6856a7090dc72c3948aeae6e1626b8..9b4c2ad4eda55e0eaf97a0b220c8417f253acc8e 100644 --- a/src/runtime2/runtime.rs +++ b/src/runtime2/runtime.rs @@ -7,7 +7,7 @@ use crate::runtime2::component::wake_up_if_sleeping; use super::communication::Message; use super::component::{CompCtx, CompPDL}; -use super::store::{ComponentStore, QueueDynMpsc, QueueDynProducer}; +use super::store::{ComponentStore, ComponentReservation, QueueDynMpsc, QueueDynProducer}; use super::scheduler::*; // ----------------------------------------------------------------------------- @@ -43,6 +43,17 @@ impl CompId { } } +/// Handle to a component that is being created. +pub(crate) struct CompReserved { + reservation: ComponentReservation, +} + +impl CompReserved { + pub(crate) fn id(&self) -> CompId { + return CompId(self.reservation.index) + } +} + /// Private fields of a component, may only be modified by a single thread at /// a time. pub(crate) struct RuntimeComp { @@ -208,10 +219,42 @@ impl RuntimeInner { // Creating/destroying components + pub(crate) fn start_create_pdl_component(&self) -> CompReserved { + self.increment_active_components(); + let reservation = self.components.reserve(); + return CompReserved{ reservation }; + } + + pub(crate) fn finish_create_pdl_component( + &self, reserved: CompReserved, + component: CompPDL, mut context: CompCtx, initially_sleeping: bool, + ) -> (CompKey, &mut RuntimeComp) { + let inbox_queue = QueueDynMpsc::new(16); + let inbox_producer = inbox_queue.producer(); + + let _id = reserved.id(); + context.id = reserved.id(); + let component = RuntimeComp { + public: CompPublic{ + sleeping: AtomicBool::new(initially_sleeping), + num_handles: AtomicU32::new(1), // the component itself acts like a handle + inbox: inbox_producer, + }, + code: component, + ctx: context, + inbox: inbox_queue, + }; + + let index = self.components.submit(reserved.reservation, component); + debug_assert_eq!(index, _id.0); + let component = self.components.get_mut(index); + + return (CompKey(index), component); + } + /// Creates a new component. Note that the public part will be properly - /// initialized, but the private fields (e.g. owned ports, peers, etc.) - /// are not. - pub(crate) fn create_pdl_component(&self, comp: CompPDL, initially_sleeping: bool) -> (CompKey, &mut RuntimeComp) { + /// initialized, but not all private fields are. + pub(crate) fn create_pdl_component(&self, comp: CompPDL, ctx: CompCtx, initially_sleeping: bool) -> (CompKey, &mut RuntimeComp) { let inbox_queue = QueueDynMpsc::new(16); let inbox_producer = inbox_queue.producer(); let comp = RuntimeComp{ @@ -221,7 +264,7 @@ impl RuntimeInner { inbox: inbox_producer, }, code: comp, - ctx: CompCtx::default(), + ctx, inbox: inbox_queue, };