diff --git a/src/runtime2/branch.rs b/src/runtime2/branch.rs index a790ff23e52fc9ae7f37e70509474ac156234248..511dfc1597390034c4913bd4a68a0b566fd6df2e 100644 --- a/src/runtime2/branch.rs +++ b/src/runtime2/branch.rs @@ -52,6 +52,35 @@ pub(crate) enum SpeculativeState { Inconsistent, // branch can never represent a local solution, so halted } +#[derive(Debug)] +pub(crate) enum PreparedStatement { + CreatedChannel((Value, Value)), + ForkedExecution(bool), + PerformedPut, + PerformedGet(ValueGroup), + None, +} + +impl PreparedStatement { + pub(crate) fn is_none(&self) -> bool { + if let PreparedStatement::None = self { + return true; + } else { + return false; + } + } + + pub(crate) fn take(&mut self) -> PreparedStatement { + if let PreparedStatement::None = self { + return PreparedStatement::None; + } else { + let mut replacement = PreparedStatement::None; + std::mem::swap(self, &mut replacement); + return replacement; + } + } +} + /// The execution state of a branch. This envelops the PDL code and the /// execution state. And derived from that: if we're ready to keep running the /// code, or if we're halted for some reason (e.g. waiting for a message). @@ -63,9 +92,7 @@ pub(crate) struct Branch { pub sync_state: SpeculativeState, pub awaiting_port: PortIdLocal, // only valid if in "awaiting message" queue. TODO: Maybe put in enum pub next_in_queue: BranchId, // used by `ExecTree`/`BranchQueue` - pub inbox: HashMap, // TODO: Remove, currently only valid in single-get/put mode - pub prepared_channel: Option<(Value, Value)>, // TODO: Maybe remove? - pub prepared_fork: Option, // TODO: See above + pub prepared: PreparedStatement, } impl BranchListItem for Branch { @@ -84,9 +111,7 @@ impl Branch { sync_state: SpeculativeState::RunningNonSync, awaiting_port: PortIdLocal::new_invalid(), next_in_queue: BranchId::new_invalid(), - inbox: HashMap::new(), - prepared_channel: None, - prepared_fork: None, + prepared: PreparedStatement::None, } } @@ -97,8 +122,7 @@ impl Branch { // (parent_branch.sync_state == SpeculativeState::RunningNonSync && !parent_branch.parent_id.is_valid()) || // (parent_branch.sync_state == SpeculativeState::HaltedAtBranchPoint) // ); // forking from non-sync, or forking from a branching point - debug_assert!(parent_branch.prepared_channel.is_none()); - debug_assert!(parent_branch.prepared_fork.is_none()); + debug_assert!(parent_branch.prepared.is_none()); Branch { id: BranchId::new(new_index), @@ -107,20 +131,9 @@ impl Branch { sync_state: SpeculativeState::RunningInSync, awaiting_port: parent_branch.awaiting_port, next_in_queue: BranchId::new_invalid(), - inbox: parent_branch.inbox.clone(), - prepared_channel: None, - prepared_fork: None, + prepared: PreparedStatement::None, } } - - /// Inserts a message into the branch for retrieval by a corresponding - /// `get(port)` call. - pub(crate) fn insert_message(&mut self, target_port: PortIdLocal, contents: ValueGroup) { - debug_assert!(target_port.is_valid()); - debug_assert!(self.awaiting_port == target_port); - self.awaiting_port = PortIdLocal::new_invalid(); - self.inbox.insert(target_port, contents); - } } /// Queue of branches. Just a little helper. @@ -295,8 +308,7 @@ impl ExecTree { branch.sync_state = SpeculativeState::RunningNonSync; debug_assert!(!branch.awaiting_port.is_valid()); branch.next_in_queue = BranchId::new_invalid(); - branch.inbox.clear(); - debug_assert!(branch.prepared_channel.is_none()); + debug_assert!(branch.prepared.is_none()); // Clear out all the queues for queue_idx in 0..NUM_QUEUES {