diff --git a/src/vt/messaging/async_op.cc b/src/vt/messaging/async_op.cc index 29599b7a81..12b8de6823 100644 --- a/src/vt/messaging/async_op.cc +++ b/src/vt/messaging/async_op.cc @@ -47,7 +47,7 @@ namespace vt { namespace messaging { AsyncOp::AsyncOp() { cur_epoch_ = theMsg()->getEpoch(); - theTerm()->produce(cur_epoch_); + theTerm()->addLocalDependency(cur_epoch_); } AsyncOp::AsyncOp(AsyncOp&& in) { @@ -56,8 +56,10 @@ AsyncOp::AsyncOp(AsyncOp&& in) { } /*virtual*/ AsyncOp::~AsyncOp() { + // This case only occurs in a moved-from instance, in which case the + // move-ee will make the matching calls if (cur_epoch_ != no_epoch) { - theTerm()->consume(cur_epoch_); + theTerm()->releaseLocalDependency(cur_epoch_); } } diff --git a/src/vt/termination/termination.cc b/src/vt/termination/termination.cc index fefadeb2ad..d6c903ec29 100644 --- a/src/vt/termination/termination.cc +++ b/src/vt/termination/termination.cc @@ -940,6 +940,24 @@ void TerminationDetector::addEpochStateDependency(EpochType ep) { } } +void TerminationDetector::addLocalDependency(EpochType epoch) { + if (epoch != any_epoch_sentinel) { + addEpochStateDependency(epoch); + } + theTerm()->produce(epoch); + any_epoch_state_.incrementDependency(); + hang_.incrementDependency(); +} + +void TerminationDetector::releaseLocalDependency(EpochType epoch) { + hang_.decrementDependency(); + any_epoch_state_.decrementDependency(); + theTerm()->consume(epoch); + if (epoch != any_epoch_sentinel) { + removeEpochStateDependency(epoch); + } +} + void TerminationDetector::finishNoActivateEpoch(EpochType const& epoch) { auto ready_iter = epoch_ready_.find(epoch); if (ready_iter == epoch_ready_.end()) { diff --git a/src/vt/termination/termination.h b/src/vt/termination/termination.h index e13178fa32..e0466b540d 100644 --- a/src/vt/termination/termination.h +++ b/src/vt/termination/termination.h @@ -622,6 +622,20 @@ struct TerminationDetector : ); public: + /** + * \brief Add a local work dependency on an epoch to stop propagation + * + * \param[in] epoch the epoch + */ + void addLocalDependency(EpochType epoch); + + /** + * \brief Release a local work dependency on an epoch to resume propagation + * + * \param[in] epoch the epoch + */ + void releaseLocalDependency(EpochType epoch); + /** * \internal \brief Make a dependency between two epochs *