Logo AND Algorithmique Numérique Distribuée

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