3 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc,
4 "Logging specific to MC (request)");
6 static char* pointer_to_string(void* pointer);
7 static char* buff_size_to_string(size_t size);
9 int MC_request_depend(smx_req_t r1, smx_req_t r2)
11 if(_surf_do_model_check == 2)
15 if (r1->issuer == r2->issuer)
18 if(r1->call == REQ_COMM_ISEND && r2->call == REQ_COMM_IRECV)
21 if(r1->call == REQ_COMM_IRECV && r2->call == REQ_COMM_ISEND)
24 if( (r1->call == REQ_COMM_ISEND || r1->call == REQ_COMM_IRECV)
25 && r2->call == REQ_COMM_WAIT){
27 if(r2->comm_wait.comm->comm.rdv == NULL)
30 smx_rdv_t rdv = r1->call == REQ_COMM_ISEND ? r1->comm_isend.rdv : r1->comm_irecv.rdv;
32 if(r2->comm_wait.comm->comm.rdv != rdv)
35 if(r2->comm_wait.comm->comm.type == SIMIX_COMM_SEND && r1->call == REQ_COMM_ISEND)
38 if(r2->comm_wait.comm->comm.type == SIMIX_COMM_RECEIVE && r1->call == REQ_COMM_IRECV)
42 if( (r2->call == REQ_COMM_ISEND || r2->call == REQ_COMM_IRECV)
43 && r1->call == REQ_COMM_WAIT){
45 if(r1->comm_wait.comm->comm.rdv != NULL)
48 smx_rdv_t rdv = r2->call == REQ_COMM_ISEND ? r2->comm_isend.rdv : r2->comm_irecv.rdv;
50 if(r1->comm_wait.comm->comm.rdv != rdv)
53 if(r1->comm_wait.comm->comm.type == SIMIX_COMM_SEND && r2->call == REQ_COMM_ISEND)
56 if(r1->comm_wait.comm->comm.type == SIMIX_COMM_RECEIVE && r2->call == REQ_COMM_IRECV)
60 /* FIXME: the following rule assumes that the result of the
61 * isend/irecv call is not stored in a buffer used in the
63 if( (r1->call == REQ_COMM_ISEND || r1->call == REQ_COMM_IRECV)
64 && r2->call == REQ_COMM_TEST)
67 /* FIXME: the following rule assumes that the result of the
68 * isend/irecv call is not stored in a buffer used in the
70 if( (r2->call == REQ_COMM_ISEND || r2->call == REQ_COMM_IRECV)
71 && r1->call == REQ_COMM_TEST)
74 if(r1->call == REQ_COMM_ISEND && r2->call == REQ_COMM_ISEND
75 && r1->comm_isend.rdv != r2->comm_isend.rdv)
78 if(r1->call == REQ_COMM_IRECV && r2->call == REQ_COMM_IRECV
79 && r1->comm_irecv.rdv != r2->comm_irecv.rdv)
82 if(r1->call == REQ_COMM_WAIT && (r2->call == REQ_COMM_WAIT || r2->call == REQ_COMM_TEST)
83 && (r1->comm_wait.comm->comm.src_proc == NULL
84 || r1->comm_wait.comm->comm.dst_proc == NULL))
87 if(r2->call == REQ_COMM_WAIT && (r1->call == REQ_COMM_WAIT || r1->call == REQ_COMM_TEST)
88 && (r2->comm_wait.comm->comm.src_proc == NULL
89 || r2->comm_wait.comm->comm.dst_proc == NULL))
92 if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
93 && r1->comm_wait.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
94 && r1->comm_wait.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
97 if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
98 && r1->comm_wait.comm->comm.src_buff != NULL
99 && r1->comm_wait.comm->comm.dst_buff != NULL
100 && r2->comm_wait.comm->comm.src_buff != NULL
101 && r2->comm_wait.comm->comm.dst_buff != NULL
102 && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
103 && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
104 && r2->comm_wait.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
107 if(r1->call == REQ_COMM_TEST &&
108 (r1->comm_test.comm == NULL
109 || r1->comm_test.comm->comm.src_buff == NULL
110 || r1->comm_test.comm->comm.dst_buff == NULL))
113 if(r2->call == REQ_COMM_TEST &&
114 (r2->comm_test.comm == NULL
115 || r2->comm_test.comm->comm.src_buff == NULL
116 || r2->comm_test.comm->comm.dst_buff == NULL))
119 if(r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
120 && r1->comm_test.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
121 && r1->comm_test.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
124 if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
125 && r1->comm_wait.comm->comm.src_buff == r2->comm_test.comm->comm.src_buff
126 && r1->comm_wait.comm->comm.dst_buff == r2->comm_test.comm->comm.dst_buff)
129 if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
130 && r1->comm_wait.comm->comm.src_buff != NULL
131 && r1->comm_wait.comm->comm.dst_buff != NULL
132 && r2->comm_test.comm->comm.src_buff != NULL
133 && r2->comm_test.comm->comm.dst_buff != NULL
134 && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.src_buff
135 && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.dst_buff
136 && r2->comm_test.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
139 if (r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
140 && r1->comm_test.comm->comm.src_buff != NULL
141 && r1->comm_test.comm->comm.dst_buff != NULL
142 && r2->comm_wait.comm->comm.src_buff != NULL
143 && r2->comm_wait.comm->comm.dst_buff != NULL
144 && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
145 && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
146 && r2->comm_wait.comm->comm.dst_buff != r1->comm_test.comm->comm.src_buff)
153 static char* pointer_to_string(void* pointer) {
155 if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
156 return bprintf("%p", pointer);
158 return xbt_strdup("(verbose only)");
161 static char* buff_size_to_string(size_t buff_size) {
163 if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
164 return bprintf("%zu", buff_size);
166 return xbt_strdup("(verbose only)");
170 char *MC_request_to_string(smx_req_t req, int value)
172 char *type = NULL, *args = NULL, *str = NULL, *p = NULL, *bs = NULL;
173 smx_action_t act = NULL;
178 type = xbt_strdup("iSend");
179 p = pointer_to_string(req->comm_isend.src_buff);
180 bs = buff_size_to_string(req->comm_isend.src_buff_size);
181 args = bprintf("src=%s, buff=%s, size=%s", req->issuer->name, p, bs);
184 size = req->comm_irecv.dst_buff_size ? *req->comm_irecv.dst_buff_size : 0;
185 type = xbt_strdup("iRecv");
186 p = pointer_to_string(req->comm_irecv.dst_buff);
187 bs = buff_size_to_string(size);
188 args = bprintf("dst=%s, buff=%s, size=%s", req->issuer->name, p, bs);
191 act = req->comm_wait.comm;
193 type = xbt_strdup("WaitTimeout");
194 p = pointer_to_string(act);
195 args = bprintf("comm=%p", p);
197 type = xbt_strdup("Wait");
198 p = pointer_to_string(act);
199 args = bprintf("comm=%s [(%lu)%s -> (%lu)%s]", p,
200 act->comm.src_proc ? act->comm.src_proc->pid : 0,
201 act->comm.src_proc ? act->comm.src_proc->name : "",
202 act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
203 act->comm.dst_proc ? act->comm.dst_proc->name : "");
207 act = req->comm_test.comm;
208 if(act->comm.src_proc == NULL || act->comm.src_proc == NULL){
209 type = xbt_strdup("Test FALSE");
210 p = pointer_to_string(act);
211 args = bprintf("comm=%s", p);
213 type = xbt_strdup("Test TRUE");
214 p = pointer_to_string(act);
215 args = bprintf("comm=%s [(%lu)%s -> (%lu)%s]", p,
216 act->comm.src_proc ? act->comm.src_proc->pid : 0,
217 act->comm.src_proc ? act->comm.src_proc->name : "",
218 act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
219 act->comm.dst_proc ? act->comm.dst_proc->name : "");
223 case REQ_COMM_WAITANY:
224 type = xbt_strdup("WaitAny");
225 p = pointer_to_string(xbt_dynar_get_as(req->comm_waitany.comms, value, smx_action_t));
226 args = bprintf("comm=%s (%d of %lu)", p,
227 value+1, xbt_dynar_length(req->comm_waitany.comms));
230 case REQ_COMM_TESTANY:
232 type = xbt_strdup("TestAny FALSE");
233 args = xbt_strdup("-");
235 type = xbt_strdup("TestAny");
236 args = bprintf("(%d of %lu)", value+1, xbt_dynar_length(req->comm_testany.comms));
244 str = bprintf("[(%lu)%s] %s (%s)", req->issuer->pid ,req->issuer->name, type, args);
252 unsigned int MC_request_testany_fail(smx_req_t req)
257 xbt_dynar_foreach(req->comm_testany.comms, cursor, action){
258 if(action->comm.src_proc && action->comm.dst_proc)
265 int MC_request_is_visible(smx_req_t req)
267 return req->call == REQ_COMM_ISEND
268 || req->call == REQ_COMM_IRECV
269 || req->call == REQ_COMM_WAIT
270 || req->call == REQ_COMM_WAITANY
271 || req->call == REQ_COMM_TEST
272 || req->call == REQ_COMM_TESTANY;
275 int MC_request_is_enabled(smx_req_t req)
277 unsigned int index = 0;
283 /* FIXME: check also that src and dst processes are not suspended */
285 /* If it has a timeout it will be always be enabled, because even if the
286 * communication is not ready, it can timeout and won't block.
287 * On the other hand if it hasn't a timeout, check if the comm is ready.*/
288 if(req->comm_wait.timeout >= 0){
291 act = req->comm_wait.comm;
292 return (act->comm.src_proc && act->comm.dst_proc);
296 case REQ_COMM_WAITANY:
297 /* Check if it has at least one communication ready */
298 xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
299 if (act->comm.src_proc && act->comm.dst_proc){
307 /* The rest of the request are always enabled */
312 int MC_request_is_enabled_by_idx(smx_req_t req, unsigned int idx)
319 /* FIXME: check also that src and dst processes are not suspended */
320 act = req->comm_wait.comm;
321 return (act->comm.src_proc && act->comm.dst_proc);
324 case REQ_COMM_WAITANY:
325 act = xbt_dynar_get_as(req->comm_waitany.comms, idx, smx_action_t);
326 return (act->comm.src_proc && act->comm.dst_proc);
329 case REQ_COMM_TESTANY:
330 act = xbt_dynar_get_as(req->comm_testany.comms, idx, smx_action_t);
331 return (act->comm.src_proc && act->comm.dst_proc);
339 int MC_process_is_enabled(smx_process_t process)
341 if (process->request.call != REQ_NO_REQ && MC_request_is_enabled(&process->request))