Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Don't send sbuff and rbuff to the MC checker
[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 <inttypes.h>
14 #include <sstream>
15
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition,
17                                 "Logging specific to MC transitions about communications");
18
19 namespace simgrid::mc {
20
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)
24     , timeout_(timeout_)
25     , comm_(comm_)
26     , mbox_(mbox_)
27     , sender_(sender_)
28     , receiver_(receiver_)
29 {
30 }
31 CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream)
32     : Transition(Type::COMM_WAIT, issuer, times_considered)
33 {
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_);
37 }
38 std::string CommWaitTransition::to_string(bool verbose) const
39 {
40   return xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s)", sender_, receiver_, mbox_,
41                             (timeout_ ? "timeout" : "no timeout"));
42 }
43 bool CommWaitTransition::depends(const Transition* other) const
44 {
45   if (other->type_ < type_)
46     return other->depends(this);
47
48   // Actions executed by the same actor are always dependent
49   if (other->aid_ == aid_)
50     return true;
51
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
55   }
56
57   return false; // Comm transitions are INDEP with non-comm transitions
58 }
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)
62     , comm_(comm_)
63     , mbox_(mbox_)
64     , sender_(sender_)
65     , receiver_(receiver_)
66 {
67 }
68 CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream)
69     : Transition(Type::COMM_TEST, issuer, times_considered)
70 {
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_);
73 }
74 std::string CommTestTransition::to_string(bool verbose) const
75 {
76   return xbt::string_printf("TestComm(from %ld to %ld, mbox=%u)", sender_, receiver_, mbox_);
77 }
78 bool CommTestTransition::depends(const Transition* other) const
79 {
80   if (other->type_ < type_)
81     return other->depends(this);
82
83   // Actions executed by the same actor are always dependent
84   if (other->aid_ == aid_)
85     return true;
86
87   if (dynamic_cast<const CommTestTransition*>(other) != nullptr)
88     return false; // Test & Test are independent
89
90   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
91     if (wait->timeout_)
92       return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
93
94     /* Wait & Test are independent */
95     return false;
96   }
97
98   return false; // Comm transitions are INDEP with non-comm transitions
99 }
100
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_)
103 {
104 }
105 CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream)
106     : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered)
107 {
108   xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_);
109 }
110 std::string CommRecvTransition::to_string(bool verbose) const
111 {
112   return xbt::string_printf("iRecv(mbox=%u)", mbox_);
113 }
114 bool CommRecvTransition::depends(const Transition* other) const
115 {
116   if (other->type_ < type_)
117     return other->depends(this);
118
119   // Actions executed by the same actor are always dependent
120   if (other->aid_ == aid_)
121     return true;
122
123   if (const auto* recv = dynamic_cast<const CommRecvTransition*>(other))
124     return mbox_ == recv->mbox_;
125
126   if (dynamic_cast<const CommSendTransition*>(other) != nullptr)
127     return false;
128
129   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
130     if (mbox_ != test->mbox_)
131       return false;
132
133     if ((aid_ != test->sender_) && (aid_ != test->receiver_))
134       return false;
135
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_)
139       return false;
140
141     return true; // DEP with other send transitions
142   }
143
144   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
145     if (wait->timeout_)
146       return true;
147
148     if (mbox_ != wait->mbox_)
149       return false;
150
151     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_))
152       return false;
153
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_)
157       return false;
158
159     return true; // DEP with other wait transitions
160   }
161
162   return false; // Comm transitions are INDEP with non-comm transitions
163 }
164
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_)
167 {
168 }
169 CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream)
170     : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered)
171 {
172   xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_);
173   XBT_DEBUG("SendTransition comm:%u mbox:%u", comm_, mbox_);
174 }
175 std::string CommSendTransition::to_string(bool verbose = false) const
176 {
177   return xbt::string_printf("iSend(mbox=%u)", mbox_);
178 }
179
180 bool CommSendTransition::depends(const Transition* other) const
181 {
182   if (other->type_ < type_)
183     return other->depends(this);
184
185   // Actions executed by the same actor are always dependent
186   if (other->aid_ == aid_)
187     return true;
188
189   if (const auto* other_isend = dynamic_cast<const CommSendTransition*>(other))
190     return mbox_ == other_isend->mbox_;
191
192   if (dynamic_cast<const CommRecvTransition*>(other) != nullptr)
193     return false;
194
195   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
196     if (mbox_ != test->mbox_)
197       return false;
198
199     if ((aid_ != test->sender_) && (aid_ != test->receiver_))
200       return false;
201
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_)
205       return false;
206
207     return true; // DEP with other test transitions
208   }
209
210   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
211     if (wait->timeout_)
212       return true;
213
214     if (mbox_ != wait->mbox_)
215       return false;
216
217     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_))
218       return false;
219
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_)
223       return false;
224
225     return true; // DEP with other wait transitions
226   }
227
228   return false; // Comm transitions are INDEP with non-comm transitions
229 }
230
231 } // namespace simgrid::mc