Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Pass the depends() from the observer to the mc::Transition for CommWait, Send and...
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 11 Feb 2022 09:24:40 +0000 (10:24 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 11 Feb 2022 11:28:18 +0000 (12:28 +0100)
src/kernel/actor/SimcallObserver.cpp
src/kernel/actor/SimcallObserver.hpp
src/mc/Transition.cpp
src/mc/Transition.hpp

index f2818db..b977abc 100644 (file)
@@ -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<CommIsendSimcall*>(other))
-    return isend->depends(this);
-
-  if (auto* irecv = dynamic_cast<CommIrecvSimcall*>(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<ActivityWaitSimcall*>(other)) {
-    if (timeout_ > 0 || wait->get_timeout() > 0)
-      return true;
-    const auto* comm1 = dynamic_cast<activity::CommImpl*>(activity_);
-    const auto* comm2 = dynamic_cast<activity::CommImpl*>(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<CommIsendSimcall*>(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<CommIrecvSimcall*>(other) != nullptr)
-    return false;
-
-#if SIMGRID_HAVE_MC // FIXME needed to access mbox_cpy
-  if (const auto* wait = dynamic_cast<ActivityWaitSimcall*>(other)) {
-    if (const auto* comm2 = dynamic_cast<activity::CommImpl*>(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<ActivityTestSimcall*>(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<CommIrecvSimcall*>(other))
-    return mbox_ == other_irecv->get_mailbox();
-
-  if (auto* isend = dynamic_cast<CommIsendSimcall*>(other))
-    return isend->depends(this);
-
-#if SIMGRID_HAVE_MC // FIXME needed to access mbox_cpy
-  if (auto* wait = dynamic_cast<ActivityWaitSimcall*>(other)) {
-    if (auto* comm2 = dynamic_cast<activity::CommImpl*>(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<ActivityTestSimcall*>(other))
-    return false;
-#endif
-
-  return true;
-}
 
 /*
 std::string CommIrecvSimcall::to_string(int times_considered) const
index 7476334..2964201 100644 (file)
@@ -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";
index 5bba8c4..a0c37f2 100644 (file)
@@ -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<const CommSendTransition*>(other))
+    return send->depends(this);
+
+  if (auto* recv = dynamic_cast<const CommRecvTransition*>(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<const CommWaitTransition*>(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<const CommRecvTransition*>(other))
+    return mbox_ == other_irecv->mbox_;
+
+  if (auto* isend = dynamic_cast<const CommSendTransition*>(other))
+    return isend->depends(this);
+
+  if (auto* wait = dynamic_cast<const CommWaitTransition*>(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<ActivityTestSimcall*>(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<const CommSendTransition*>(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<const CommRecvTransition*>(other) != nullptr)
+    return false;
+
+  if (const auto* wait = dynamic_cast<const CommWaitTransition*>(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<ActivityTestSimcall*>(other))
+    return false;
+#endif
+
+  return true;
+}
 
 Transition* recv_transition(aid_t issuer, int times_considered, kernel::actor::SimcallObserver::Simcall simcall,
                             char* buffer)
index 88929bc..88e7747 100644 (file)
@@ -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 */