X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/c19a107a096f503e67217fb178fa98eb742ceb4d..f3978ee8083967b9249494916e755a3a855435d0:/src/kernel/activity/ActivityImpl.cpp diff --git a/src/kernel/activity/ActivityImpl.cpp b/src/kernel/activity/ActivityImpl.cpp index b82915e4cb..70e80323d3 100644 --- a/src/kernel/activity/ActivityImpl.cpp +++ b/src/kernel/activity/ActivityImpl.cpp @@ -5,8 +5,11 @@ #include "src/kernel/activity/ActivityImpl.hpp" #include "simgrid/modelchecker.h" +#include "src/kernel/activity/SynchroRaw.hpp" +#include "src/kernel/actor/SimcallObserver.hpp" #include "src/mc/mc_replay.hpp" #include "src/simix/smx_private.hpp" +#include #include // isfinite() XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_process); @@ -27,6 +30,14 @@ void ActivityImpl::register_simcall(smx_simcall_t simcall) simcall->issuer_->waiting_synchro_ = this; } +void ActivityImpl::unregister_simcall(smx_simcall_t simcall) +{ + // Remove the first occurrence of simcall: + auto j = boost::range::find(simcalls_, simcall); + if (j != simcalls_.end()) + simcalls_.erase(j); +} + void ActivityImpl::clean_action() { if (surf_action_) { @@ -42,43 +53,7 @@ double ActivityImpl::get_remaining() const const char* ActivityImpl::get_state_str() const { - switch (state_) { - case State::WAITING: - return "WAITING"; - - case State::READY: - return "READY"; - - case State::RUNNING: - return "RUNNING"; - - case State::CANCELED: - return "CANCELED"; - - case State::FAILED: - return "FAILED"; - - case State::DONE: - return "DONE"; - - case State::SRC_HOST_FAILURE: - return "SRC_HOST_FAILURE"; - - case State::DST_HOST_FAILURE: - return "DST_HOST_FAILURE"; - - case State::TIMEOUT: - return "TIMEOUT"; - - case State::SRC_TIMEOUT: - return "SRC_TIMEOUT"; - case State::DST_TIMEOUT: - return "DST_TIMEOUT"; - - case State::LINK_FAILURE: - return "LINK_FAILURE"; - } - THROW_IMPOSSIBLE; + return to_c_str(state_); } bool ActivityImpl::test() @@ -92,33 +67,28 @@ bool ActivityImpl::test() void ActivityImpl::wait_for(actor::ActorImpl* issuer, double timeout) { - XBT_DEBUG("Wait for execution of synchro %p, state %d", this, (int)state_); + XBT_DEBUG("Wait for execution of synchro %p, state %s", this, to_c_str(state_)); xbt_assert(std::isfinite(timeout), "timeout is not finite!"); /* Associate this simcall to the synchro */ register_simcall(&issuer->simcall_); - if (MC_is_active() || MC_record_replay_is_active()) { - int idx = SIMCALL_GET_MC_VALUE(issuer->simcall_); - if (idx == 0) { - state_ = simgrid::kernel::activity::State::DONE; - } else { - /* If we reached this point, the wait simcall must have a timeout */ - /* Otherwise it shouldn't be enabled and executed by the MC */ - if (timeout < 0.0) - THROW_IMPOSSIBLE; - state_ = simgrid::kernel::activity::State::TIMEOUT; - } - finish(); - return; - } + xbt_assert(not MC_is_active() && not MC_record_replay_is_active(), "MC is currently not supported here."); /* If the synchro is already finished then perform the error handling */ - if (state_ != simgrid::kernel::activity::State::RUNNING) + if (state_ != State::RUNNING) { finish(); - else { - /* we need a sleep action (even when there is no timeout) to be notified of host failures */ - set_timeout(timeout); + } else { + /* we need a sleep action (even when the timeout is infinite) to be notified of host failures */ + RawImplPtr synchro(new RawImpl([this, issuer]() { + this->unregister_simcall(&issuer->simcall_); + issuer->waiting_synchro_ = nullptr; + auto* observer = dynamic_cast(issuer->simcall_.observer_); + xbt_assert(observer != nullptr); + observer->set_result(true); + })); + synchro->set_host(issuer->get_host()).set_timeout(timeout).start(); + synchro->register_simcall(&issuer->simcall_); } } @@ -149,12 +119,12 @@ void ActivityImpl::cancel() } // boost::intrusive_ptr support: -void intrusive_ptr_add_ref(simgrid::kernel::activity::ActivityImpl* activity) +void intrusive_ptr_add_ref(ActivityImpl* activity) { activity->refcount_.fetch_add(1, std::memory_order_relaxed); } -void intrusive_ptr_release(simgrid::kernel::activity::ActivityImpl* activity) +void intrusive_ptr_release(ActivityImpl* activity) { if (activity->refcount_.fetch_sub(1, std::memory_order_release) == 1) { std::atomic_thread_fence(std::memory_order_acquire);