From: Martin Quinson Date: Fri, 11 Feb 2022 09:24:40 +0000 (+0100) Subject: Pass the depends() from the observer to the mc::Transition for CommWait, Send and... X-Git-Tag: v3.31~454 X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/cea04af9af482c60d0b42fbc58bc3478a7e2c347 Pass the depends() from the observer to the mc::Transition for CommWait, Send and Recv --- diff --git a/src/kernel/actor/SimcallObserver.cpp b/src/kernel/actor/SimcallObserver.cpp index f2818db656..b977abcb6c 100644 --- a/src/kernel/actor/SimcallObserver.cpp +++ b/src/kernel/actor/SimcallObserver.cpp @@ -291,38 +291,6 @@ bool ActivityWaitSimcall::is_enabled() const return (comm->src_actor_ && comm->dst_actor_); } -bool ActivityWaitSimcall::depends(SimcallObserver* other) -{ - if (get_issuer() == other->get_issuer()) - return false; - - if (auto* isend = dynamic_cast(other)) - return isend->depends(this); - - if (auto* irecv = dynamic_cast(other)) - return irecv->depends(this); - - /* Timeouts in wait transitions are not considered by the independence theorem, thus assumed dependent */ - if (const auto* wait = dynamic_cast(other)) { - if (timeout_ > 0 || wait->get_timeout() > 0) - return true; - const auto* comm1 = dynamic_cast(activity_); - const auto* comm2 = dynamic_cast(wait->get_activity()); - - if (comm1 == nullptr || comm2 == nullptr) // One wait at least in not on a Comm - return true; - - if (comm1->src_buff_ == comm2->src_buff_ && comm1->dst_buff_ == comm2->dst_buff_) - return false; - if (comm1->src_buff_ != nullptr && comm1->dst_buff_ != nullptr && comm2->src_buff_ != nullptr && - comm2->dst_buff_ != nullptr && comm1->dst_buff_ != comm2->src_buff_ && comm1->dst_buff_ != comm2->dst_buff_ && - comm2->dst_buff_ != comm1->src_buff_) - return false; - } - - return true; -} - std::string ActivityWaitSimcall::dot_label(int times_considered) const { std::string res = SimcallObserver::dot_label(times_considered); @@ -374,45 +342,6 @@ void ActivityWaitanySimcall::prepare(int times_considered) next_value_ = times_considered; } -bool CommIsendSimcall::depends(SimcallObserver* other) -{ - if (get_issuer() == other->get_issuer()) - return false; - - if (const auto* other_isend = dynamic_cast(other)) - return mbox_ == other_isend->get_mailbox(); - - // FIXME: Not in the former dependency check because of the ordering but seems logical to add it - if (dynamic_cast(other) != nullptr) - return false; - -#if SIMGRID_HAVE_MC // FIXME needed to access mbox_cpy - if (const auto* wait = dynamic_cast(other)) { - if (const auto* comm2 = dynamic_cast(wait->get_activity())) { // this is a Comm::wait_for - const auto* mbox1 = mbox_; - const auto* mbox2 = comm2->mbox_cpy; - - if (mbox1 != mbox2 && wait->get_timeout() <= 0) - return false; - - if ((get_issuer() != comm2->src_actor_.get()) && (get_issuer() != comm2->dst_actor_.get()) && - wait->get_timeout() <= 0) - return false; - - if (comm2->type_ == activity::CommImpl::Type::SEND && comm2->src_buff_ != src_buff_ && wait->get_timeout() <= 0) - return false; - } - } -#endif - /* FIXME: the following rule assumes that the result of the isend/irecv call is not stored in a buffer used in the - * test call. */ -#if 0 - if (dynamic_cast(other)) - return false; -#endif - - return true; -} void CommIsendSimcall::serialize(Simcall& type, char* buffer) { type = Simcall::ISEND; @@ -429,45 +358,6 @@ void CommIrecvSimcall::serialize(Simcall& type, char* buffer) strcpy(buffer, stream.str().c_str()); } -bool CommIrecvSimcall::depends(SimcallObserver* other) -{ - if (get_issuer() == other->get_issuer()) - return false; - - if (const auto* other_irecv = dynamic_cast(other)) - return mbox_ == other_irecv->get_mailbox(); - - if (auto* isend = dynamic_cast(other)) - return isend->depends(this); - -#if SIMGRID_HAVE_MC // FIXME needed to access mbox_cpy - if (auto* wait = dynamic_cast(other)) { - if (auto* comm2 = dynamic_cast(wait->get_activity())) { // this is a Comm::wait_for - const auto* mbox1 = mbox_; - const auto* mbox2 = comm2->mbox_cpy; - - if (mbox1 != mbox2 && wait->get_timeout() <= 0) - return false; - - if ((get_issuer() != comm2->src_actor_.get()) && (get_issuer() != comm2->dst_actor_.get()) && - wait->get_timeout() <= 0) - return false; - - if (comm2->type_ == activity::CommImpl::Type::RECEIVE && comm2->dst_buff_ != dst_buff_ && - wait->get_timeout() <= 0) - return false; - } - } -#endif - /* FIXME: the following rule assumes that the result of the isend/irecv call is not stored in a buffer used in the - * test call. */ -#if 0 - if (dynamic_cast(other)) - return false; -#endif - - return true; -} /* std::string CommIrecvSimcall::to_string(int times_considered) const diff --git a/src/kernel/actor/SimcallObserver.hpp b/src/kernel/actor/SimcallObserver.hpp index 74763346f1..29642013de 100644 --- a/src/kernel/actor/SimcallObserver.hpp +++ b/src/kernel/actor/SimcallObserver.hpp @@ -216,7 +216,6 @@ public: void serialize(Simcall& type, char* buffer); bool is_visible() const override { return true; } bool is_enabled() const override; - bool depends(SimcallObserver* other) override; std::string dot_label(int times_considered) const override; activity::ActivityImpl* get_activity() const { return activity_; } void set_activity(activity::ActivityImpl* activity) { activity_ = activity; } @@ -283,7 +282,6 @@ public: clean_fun_, copy_data_fun_, payload_, detached_); } bool is_visible() const override { return true; } - bool depends(SimcallObserver* other) override; std::string dot_label(int times_considered) const override { return SimcallObserver::dot_label(times_considered) + "iSend"; @@ -328,7 +326,6 @@ public: } void serialize(Simcall& type, char* buffer) override; bool is_visible() const override { return true; } - bool depends(SimcallObserver* other) override; std::string dot_label(int times_considered) const override { return SimcallObserver::dot_label(times_considered) + "iRecv"; diff --git a/src/mc/Transition.cpp b/src/mc/Transition.cpp index 5bba8c43eb..a0c37f24e9 100644 --- a/src/mc/Transition.cpp +++ b/src/mc/Transition.cpp @@ -54,14 +54,40 @@ CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, char* std::string CommWaitTransition::to_string(bool verbose) { textual_ = Transition::to_string(verbose); - textual_ += xbt::string_printf("[src=%ld -> dst=%ld, mbox=%u, tout=%f", sender_, receiver_, mbox_, timeout_); + textual_ += + xbt::string_printf("%ld: WaitComm(from %ld to %ld, mbox=%u, tout=%f", aid_, sender_, receiver_, mbox_, timeout_); if (verbose) { textual_ += ", src_buff=" + xbt::string_printf("%p", src_buff_) + ", size=" + std::to_string(size_); textual_ += ", dst_buff=" + xbt::string_printf("%p", dst_buff_); } - textual_ += "]"; + textual_ += ")"; return textual_; } +bool CommWaitTransition::depends(const Transition* other) const +{ + if (aid_ == other->aid_) + return false; + + if (auto* send = dynamic_cast(other)) + return send->depends(this); + + if (auto* recv = dynamic_cast(other)) + return recv->depends(this); + + /* Timeouts in wait transitions are not considered by the independence theorem, thus assumed dependent */ + if (const auto* wait = dynamic_cast(other)) { + if (timeout_ > 0 || wait->timeout_ > 0) + return true; + + if (src_buff_ == wait->src_buff_ && dst_buff_ == wait->dst_buff_) + return false; + if (src_buff_ != nullptr && dst_buff_ != nullptr && wait->src_buff_ != nullptr && wait->dst_buff_ != nullptr && + dst_buff_ != wait->src_buff_ && dst_buff_ != wait->dst_buff_ && dst_buff_ != src_buff_) + return false; + } + + return true; +} CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, char* buffer) : Transition(issuer, times_considered) @@ -71,12 +97,47 @@ CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, char* } std::string CommRecvTransition::to_string(bool verbose) { - textual_ = xbt::string_printf("iRecv(recver=%ld mbox=%u", aid_, mbox_); + textual_ = xbt::string_printf("%ld: Recv(mbox=%u", aid_, mbox_); if (verbose) textual_ += ", buff=" + xbt::string_printf("%p", dst_buff_); textual_ += ")"; return textual_; } +bool CommRecvTransition::depends(const Transition* other) const +{ + if (aid_ == other->aid_) + return false; + + if (const auto* other_irecv = dynamic_cast(other)) + return mbox_ == other_irecv->mbox_; + + if (auto* isend = dynamic_cast(other)) + return isend->depends(this); + + if (auto* wait = dynamic_cast(other)) { + if (wait->timeout_ > 0) + return true; + + if (mbox_ != wait->mbox_) + return false; + + if ((aid_ != wait->sender_) && (aid_ != wait->receiver_)) + return false; + + if (wait->dst_buff_ != dst_buff_) + return false; + } + + /* FIXME: the following rule assumes that the result of the isend/irecv call is not stored in a buffer used in the + * test call. */ +#if 0 + if (dynamic_cast(other)) + return false; +#endif + + return true; +} + CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, char* buffer) : Transition(issuer, times_considered) { @@ -85,12 +146,47 @@ CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, char* } std::string CommSendTransition::to_string(bool verbose = false) { - textual_ = xbt::string_printf("iSend(sender=%ld mbox=%u", aid_, mbox_); + textual_ = xbt::string_printf("%ld: Send(mbox=%u", aid_, mbox_); if (verbose) textual_ += ", buff=" + xbt::string_printf("%p", src_buff_) + ", size=" + std::to_string(size_); textual_ += ")"; return textual_; } +bool CommSendTransition::depends(const Transition* other) const +{ + if (aid_ == other->aid_) + return false; + + if (const auto* other_isend = dynamic_cast(other)) + return mbox_ == other_isend->mbox_; + + // FIXME: Not in the former dependency check because of the ordering but seems logical to add it + if (dynamic_cast(other) != nullptr) + return false; + + if (const auto* wait = dynamic_cast(other)) { + if (wait->timeout_ > 0) + return true; + + if (mbox_ != wait->mbox_) + return false; + + if ((aid_ != wait->sender_) && (aid_ != wait->receiver_)) + return false; + + if (wait->src_buff_ != src_buff_) + return false; + } + + /* FIXME: the following rule assumes that the result of the isend/irecv call is not stored in a buffer used in the + * test call. */ +#if 0 + if (dynamic_cast(other)) + return false; +#endif + + return true; +} Transition* recv_transition(aid_t issuer, int times_considered, kernel::actor::SimcallObserver::Simcall simcall, char* buffer) diff --git a/src/mc/Transition.hpp b/src/mc/Transition.hpp index 88929bc749..88e7747905 100644 --- a/src/mc/Transition.hpp +++ b/src/mc/Transition.hpp @@ -57,7 +57,7 @@ public: /* Moves the application toward a path that was already explored, but don't change the current transition */ void replay() const; - virtual bool depends(Transition* other) { return true; } + virtual bool depends(const Transition* other) const { return true; } /* Returns the total amount of transitions executed so far (for statistics) */ static unsigned long get_executed_transitions() { return executed_transitions_; } @@ -65,6 +65,9 @@ public: static unsigned long get_replayed_transitions() { return replayed_transitions_; } }; +class CommSendTransition; +class CommRecvTransition; + class CommWaitTransition : public Transition { double timeout_; uintptr_t comm_; @@ -74,10 +77,13 @@ class CommWaitTransition : public Transition { unsigned char* src_buff_; unsigned char* dst_buff_; size_t size_; + friend CommSendTransition; + friend CommRecvTransition; public: CommWaitTransition(aid_t issuer, int times_considered, char* buffer); std::string to_string(bool verbose) override; + bool depends(const Transition* other) const override; }; class CommRecvTransition : public Transition { @@ -87,6 +93,7 @@ class CommRecvTransition : public Transition { public: CommRecvTransition(aid_t issuer, int times_considered, char* buffer); std::string to_string(bool verbose) override; + bool depends(const Transition* other) const override; }; class CommSendTransition : public Transition { @@ -97,6 +104,7 @@ class CommSendTransition : public Transition { public: CommSendTransition(aid_t issuer, int times_considered, char* buffer); std::string to_string(bool verbose) override; + bool depends(const Transition* other) const override; }; /** Make a new transition from serialized description */