From 4e7d28a38654268ba0c1a58313d1578b575a3672 Mon Sep 17 00:00:00 2001 From: Rahul Butani Date: Sat, 15 Feb 2020 16:35:00 -0600 Subject: [PATCH] control: (rpc) try spinning until all futures in the batch resolve as our reset strategy re: #48 --- baseline-sim/src/sim.rs | 17 ++++++++++++++++- traits/src/control/rpc/controller.rs | 11 ++++++++++- traits/src/control/rpc/futures.rs | 4 +++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/baseline-sim/src/sim.rs b/baseline-sim/src/sim.rs index 118603a0..671336ba 100644 --- a/baseline-sim/src/sim.rs +++ b/baseline-sim/src/sim.rs @@ -509,7 +509,22 @@ where fn reset(&mut self) { self.state = State::Paused; InstructionInterpreter::reset(&mut self.interp); - self.shared_state.as_ref().map(|s| s.reset()); + self.state = State::Paused; + + // // As mentioned in control/rpc/controller.rs: For now, we're handling + // // this by having the controller block until all current futures resolve + // // themselves. See the comment in rpc/futures.rs on + // // `EventFutureSharedState::reset` for more details. + // // + // // Real implementors of `Control::reset` should call pause before + // // calling reset! Otherwise this spin lock will never exit. + // if let Some(shared_state) = self.shared_state.as_ref() { + // while !shared_state.is_clean() { + // core::sync::atomic::spin_loop_hint(); + // } + + // shared_state.reset(); + // } } fn get_error(&self) -> Option { diff --git a/traits/src/control/rpc/controller.rs b/traits/src/control/rpc/controller.rs index e688ee12..6c7a6cf8 100644 --- a/traits/src/control/rpc/controller.rs +++ b/traits/src/control/rpc/controller.rs @@ -261,7 +261,16 @@ where fn reset(&mut self) { // Drop all pending futures: // (if one of these futures is polled again, bad bad things will happen; TODO) - self.shared_state.reset(); + + // For now, we're handling this by having the controller block until all + // current futures resolve themselves. See the comment in rpc/futures.rs + // on `EventFutureSharedState::reset` for more details. + // + // Real implementors of `Control::reset` should call pause before + // calling reset! Otherwise this spin lock will never exit. + // while !self.shared_state.is_clean() { core::sync::atomic::spin_loop_hint(); } + + // self.shared_state.reset(); ctrl!(self, Reset, R::Reset) } diff --git a/traits/src/control/rpc/futures.rs b/traits/src/control/rpc/futures.rs index 43d28ce3..193cbe70 100644 --- a/traits/src/control/rpc/futures.rs +++ b/traits/src/control/rpc/futures.rs @@ -301,7 +301,9 @@ impl SharedStateState { } fn reset(&mut self) { - *self = SharedStateState::Dormant; // TODO: currently pending futures! + assert!(self.is_clean(), "Tried to reset before all Futures resolved!"); + + *self = SharedStateState::Dormant; } }