1 /* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "src/mc/transition/TransitionComm.hpp"
7 #include "simgrid/config.h"
8 #include "src/mc/api/RemoteApp.hpp"
9 #include "src/mc/api/State.hpp"
10 #include "xbt/asserts.h"
11 #include "xbt/string.hpp"
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition,
17 "Logging specific to MC transitions about communications");
19 namespace simgrid::mc {
21 CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, bool timeout_, unsigned comm_, aid_t sender_,
22 aid_t receiver_, unsigned mbox_)
23 : Transition(Type::COMM_WAIT, issuer, times_considered)
28 , receiver_(receiver_)
31 CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream)
32 : Transition(Type::COMM_WAIT, issuer, times_considered)
34 xbt_assert(stream >> timeout_ >> comm_ >> sender_ >> receiver_ >> mbox_ >> call_location_);
35 XBT_DEBUG("CommWaitTransition %s comm:%u, sender:%ld receiver:%ld mbox:%u", (timeout_ ? "timeout" : "no-timeout"),
36 comm_, sender_, receiver_, mbox_);
38 std::string CommWaitTransition::to_string(bool verbose) const
40 return xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s)", sender_, receiver_, mbox_,
41 (timeout_ ? "timeout" : "no timeout"));
43 bool CommWaitTransition::depends(const Transition* other) const
45 if (other->type_ < type_)
46 return other->depends(this);
48 // Actions executed by the same actor are always dependent
49 if (other->aid_ == aid_)
52 if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
53 if (timeout_ || wait->timeout_)
54 return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
57 return false; // Comm transitions are INDEP with non-comm transitions
59 CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, unsigned comm_, aid_t sender_,
60 aid_t receiver_, unsigned mbox_)
61 : Transition(Type::COMM_TEST, issuer, times_considered)
65 , receiver_(receiver_)
68 CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream)
69 : Transition(Type::COMM_TEST, issuer, times_considered)
71 xbt_assert(stream >> comm_ >> sender_ >> receiver_ >> mbox_ >> call_location_);
72 XBT_DEBUG("CommTestTransition comm:%u, sender:%ld receiver:%ld mbox:%u", comm_, sender_, receiver_, mbox_);
74 std::string CommTestTransition::to_string(bool verbose) const
76 return xbt::string_printf("TestComm(from %ld to %ld, mbox=%u)", sender_, receiver_, mbox_);
78 bool CommTestTransition::depends(const Transition* other) const
80 if (other->type_ < type_)
81 return other->depends(this);
83 // Actions executed by the same actor are always dependent
84 if (other->aid_ == aid_)
87 if (dynamic_cast<const CommTestTransition*>(other) != nullptr)
88 return false; // Test & Test are independent
90 if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
92 return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
94 /* Wait & Test are independent */
98 return false; // Comm transitions are INDEP with non-comm transitions
101 CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_)
102 : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered), comm_(comm_), mbox_(mbox_), tag_(tag_)
105 CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream)
106 : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered)
108 xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_);
110 std::string CommRecvTransition::to_string(bool verbose) const
112 return xbt::string_printf("iRecv(mbox=%u)", mbox_);
114 bool CommRecvTransition::depends(const Transition* other) const
116 if (other->type_ < type_)
117 return other->depends(this);
119 // Actions executed by the same actor are always dependent
120 if (other->aid_ == aid_)
123 if (const auto* recv = dynamic_cast<const CommRecvTransition*>(other))
124 return mbox_ == recv->mbox_;
126 if (dynamic_cast<const CommSendTransition*>(other) != nullptr)
129 if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
130 if (mbox_ != test->mbox_)
133 if ((aid_ != test->sender_) && (aid_ != test->receiver_))
136 // If the test is checking a paired comm already, we're independent!
137 // If we happen to make up that pair, then we're dependent...
138 if (test->comm_ != comm_)
141 return true; // DEP with other send transitions
144 if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
148 if (mbox_ != wait->mbox_)
151 if ((aid_ != wait->sender_) && (aid_ != wait->receiver_))
154 // If the wait is waiting on a paired comm already, we're independent!
155 // If we happen to make up that pair, then we're dependent...
156 if ((aid_ != wait->aid_) && wait->comm_ != comm_)
159 return true; // DEP with other wait transitions
162 return false; // Comm transitions are INDEP with non-comm transitions
165 CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_)
166 : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered), comm_(comm_), mbox_(mbox_), tag_(tag_)
169 CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream)
170 : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered)
172 xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_);
173 XBT_DEBUG("SendTransition comm:%u mbox:%u", comm_, mbox_);
175 std::string CommSendTransition::to_string(bool verbose = false) const
177 return xbt::string_printf("iSend(mbox=%u)", mbox_);
180 bool CommSendTransition::depends(const Transition* other) const
182 if (other->type_ < type_)
183 return other->depends(this);
185 // Actions executed by the same actor are always dependent
186 if (other->aid_ == aid_)
189 if (const auto* other_isend = dynamic_cast<const CommSendTransition*>(other))
190 return mbox_ == other_isend->mbox_;
192 if (dynamic_cast<const CommRecvTransition*>(other) != nullptr)
195 if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
196 if (mbox_ != test->mbox_)
199 if ((aid_ != test->sender_) && (aid_ != test->receiver_))
202 // If the test is checking a paired comm already, we're independent!
203 // If we happen to make up that pair, then we're dependent...
204 if (test->comm_ != comm_)
207 return true; // DEP with other test transitions
210 if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
214 if (mbox_ != wait->mbox_)
217 if ((aid_ != wait->sender_) && (aid_ != wait->receiver_))
220 // If the wait is waiting on a paired comm already, we're independent!
221 // If we happen to make up that pair, then we're dependent...
222 if ((aid_ != wait->aid_) && wait->comm_ != comm_)
225 return true; // DEP with other wait transitions
228 return false; // Comm transitions are INDEP with non-comm transitions
231 } // namespace simgrid::mc