Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[project-description] Fix extraction of the ns-3 version.
[simgrid.git] / src / mc / transition / TransitionComm.cpp
1 /* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 #include "src/mc/transition/TransitionComm.hpp"
7 #include "xbt/asserts.h"
8 #include <simgrid/config.h>
9 #if SIMGRID_HAVE_MC
10 #include "src/mc/ModelChecker.hpp"
11 #include "src/mc/Session.hpp"
12 #include "src/mc/api/State.hpp"
13 #endif
14
15 #include <sstream>
16
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition,
18                                 "Logging specific to MC transitions about communications");
19
20 namespace simgrid::mc {
21
22 CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream)
23     : Transition(Type::COMM_WAIT, issuer, times_considered)
24 {
25   xbt_assert(stream >> timeout_ >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_);
26   XBT_DEBUG("CommWaitTransition %s comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR
27             " rbuff:%" PRIxPTR " size:%zu",
28             (timeout_ ? "timeout" : "no-timeout"), comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_);
29 }
30 std::string CommWaitTransition::to_string(bool verbose) const
31 {
32   auto res = xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s", sender_, receiver_, mbox_,
33                                 (timeout_ ? "timeout" : "no timeout"));
34   if (verbose) {
35     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
36     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
37   }
38   res += ")";
39   return res;
40 }
41 bool CommWaitTransition::depends(const Transition* other) const
42 {
43   if (aid_ == other->aid_)
44     return false;
45
46   if (other->type_ < type_)
47     return other->depends(this);
48
49   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
50     if (timeout_ || wait->timeout_)
51       return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
52
53     if (sbuff_ == wait->sbuff_ && rbuff_ == wait->rbuff_)
54       return false;
55     if (sbuff_ != 0 && rbuff_ != 0 && wait->sbuff_ != 0 && wait->rbuff_ != 0 && rbuff_ != wait->sbuff_ &&
56         rbuff_ != wait->rbuff_ && rbuff_ != sbuff_)
57       return false;
58
59     return true;
60   }
61
62   return false; // Comm transitions are INDEP with non-comm transitions
63 }
64 CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream)
65     : Transition(Type::COMM_TEST, issuer, times_considered)
66 {
67   xbt_assert(stream >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_);
68   XBT_DEBUG("CommTestTransition comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR " rbuff:%" PRIxPTR
69             " size:%zu",
70             comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_);
71 }
72 std::string CommTestTransition::to_string(bool verbose) const
73 {
74   auto res = xbt::string_printf("TestComm(from %ld to %ld, mbox=%u", sender_, receiver_, mbox_);
75   if (verbose) {
76     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
77     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
78   }
79   res += ")";
80   return res;
81 }
82 bool CommTestTransition::depends(const Transition* other) const
83 {
84   if (aid_ == other->aid_)
85     return false;
86
87   if (other->type_ < type_)
88     return other->depends(this);
89
90   if (dynamic_cast<const CommTestTransition*>(other) != nullptr)
91     return false; // Test & Test are independent
92
93   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
94     if (wait->timeout_)
95       return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
96
97     /* Wait & Test are independent */
98     return false;
99   }
100
101   return false; // Comm transitions are INDEP with non-comm transitions
102 }
103
104 CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream)
105     : Transition(Type::COMM_RECV, issuer, times_considered)
106 {
107   xbt_assert(stream >> comm_ >> mbox_ >> rbuff_ >> tag_);
108 }
109 std::string CommRecvTransition::to_string(bool verbose) const
110 {
111   auto res = xbt::string_printf("iRecv(mbox=%u", mbox_);
112   if (verbose)
113     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
114   res += ")";
115   return res;
116 }
117 bool CommRecvTransition::depends(const Transition* other) const
118 {
119   if (aid_ == other->aid_)
120     return false;
121
122   if (other->type_ < type_)
123     return other->depends(this);
124
125   if (const auto* recv = dynamic_cast<const CommRecvTransition*>(other))
126     return mbox_ == recv->mbox_;
127
128   if (dynamic_cast<const CommSendTransition*>(other) != nullptr)
129     return false;
130
131   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
132     if (mbox_ != test->mbox_)
133       return false;
134
135     if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->rbuff_ != rbuff_))
136       return false;
137
138     return true; // DEP with other send transitions
139   }
140
141   if (auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
142     if (wait->timeout_)
143       return true;
144
145     if (mbox_ != wait->mbox_)
146       return false;
147
148     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->rbuff_ != rbuff_))
149       return false;
150
151     return true; // DEP with other wait transitions
152   }
153
154   return false; // Comm transitions are INDEP with non-comm transitions
155 }
156
157 CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream)
158     : Transition(Type::COMM_SEND, issuer, times_considered)
159 {
160   xbt_assert(stream >> comm_ >> mbox_ >> sbuff_ >> size_ >> tag_);
161   XBT_DEBUG("SendTransition comm:%" PRIxPTR " mbox:%u sbuff:%" PRIxPTR " size:%zu", comm_, mbox_, sbuff_, size_);
162 }
163 std::string CommSendTransition::to_string(bool verbose = false) const
164 {
165   auto res = xbt::string_printf("iSend(mbox=%u", mbox_);
166   if (verbose)
167     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
168   res += ")";
169   return res;
170 }
171
172 bool CommSendTransition::depends(const Transition* other) const
173 {
174   if (aid_ == other->aid_)
175     return false;
176
177   if (other->type_ < type_)
178     return other->depends(this);
179
180   if (const auto* other_isend = dynamic_cast<const CommSendTransition*>(other))
181     return mbox_ == other_isend->mbox_;
182
183   if (dynamic_cast<const CommRecvTransition*>(other) != nullptr)
184     return false;
185
186   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
187     if (mbox_ != test->mbox_)
188       return false;
189
190     if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->sbuff_ != sbuff_))
191       return false;
192
193     return true; // DEP with other test transitions
194   }
195
196   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
197     if (wait->timeout_)
198       return true;
199
200     if (mbox_ != wait->mbox_)
201       return false;
202
203     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->sbuff_ != sbuff_))
204       return false;
205
206     return true; // DEP with other wait transitions
207   }
208
209   return false; // Comm transitions are INDEP with non-comm transitions
210 }
211
212 } // namespace simgrid::mc