1 /* Copyright (c) 2008-2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #include "mc_request.h"
9 #include "mc_private.h"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc,
12 "Logging specific to MC (request)");
14 static char *pointer_to_string(void *pointer);
15 static char *buff_size_to_string(size_t size);
17 int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2)
19 if (mc_reduce_kind == e_mc_reduce_none)
22 if (r1->issuer == r2->issuer)
25 /* Wait with timeout transitions are not considered by the independance theorem, thus we consider them as dependant with all other transitions */
26 if ((r1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r1) > 0)
27 || (r2->call == SIMCALL_COMM_WAIT
28 && simcall_comm_wait__get__timeout(r2) > 0))
31 if (r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_IRECV)
34 if (r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_ISEND)
37 if ((r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
38 && r2->call == SIMCALL_COMM_WAIT) {
42 SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r1) :
43 simcall_comm_irecv__get__rdv(r1);
45 if (rdv != simcall_comm_wait__get__comm(r2)->comm.rdv_cpy
46 && simcall_comm_wait__get__timeout(r2) <= 0)
49 if ((r1->issuer != simcall_comm_wait__get__comm(r2)->comm.src_proc)
50 && (r1->issuer != simcall_comm_wait__get__comm(r2)->comm.dst_proc)
51 && simcall_comm_wait__get__timeout(r2) <= 0)
54 if ((r1->call == SIMCALL_COMM_ISEND)
55 && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND)
56 && (simcall_comm_wait__get__comm(r2)->comm.src_buff !=
57 simcall_comm_isend__get__src_buff(r1))
58 && simcall_comm_wait__get__timeout(r2) <= 0)
61 if ((r1->call == SIMCALL_COMM_IRECV)
62 && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE)
63 && (simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
64 simcall_comm_irecv__get__dst_buff(r1))
65 && simcall_comm_wait__get__timeout(r2) <= 0)
69 if ((r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
70 && r1->call == SIMCALL_COMM_WAIT) {
74 SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r2) :
75 simcall_comm_irecv__get__rdv(r2);
77 if (rdv != simcall_comm_wait__get__comm(r1)->comm.rdv_cpy
78 && simcall_comm_wait__get__timeout(r1) <= 0)
81 if ((r2->issuer != simcall_comm_wait__get__comm(r1)->comm.src_proc)
82 && (r2->issuer != simcall_comm_wait__get__comm(r1)->comm.dst_proc)
83 && simcall_comm_wait__get__timeout(r1) <= 0)
86 if ((r2->call == SIMCALL_COMM_ISEND)
87 && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND)
88 && (simcall_comm_wait__get__comm(r1)->comm.src_buff !=
89 simcall_comm_isend__get__src_buff(r2))
90 && simcall_comm_wait__get__timeout(r1) <= 0)
93 if ((r2->call == SIMCALL_COMM_IRECV)
94 && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE)
95 && (simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
96 simcall_comm_irecv__get__dst_buff(r2))
97 && simcall_comm_wait__get__timeout(r1) <= 0)
101 /* FIXME: the following rule assumes that the result of the
102 * isend/irecv call is not stored in a buffer used in the
104 /*if( (r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
105 && r2->call == SIMCALL_COMM_TEST)
108 /* FIXME: the following rule assumes that the result of the
109 * isend/irecv call is not stored in a buffer used in the
111 /*if( (r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
112 && r1->call == SIMCALL_COMM_TEST)
115 if (r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_ISEND
116 && simcall_comm_isend__get__rdv(r1) != simcall_comm_isend__get__rdv(r2))
119 if (r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_IRECV
120 && simcall_comm_irecv__get__rdv(r1) != simcall_comm_irecv__get__rdv(r2))
123 if (r1->call == SIMCALL_COMM_WAIT
124 && (r2->call == SIMCALL_COMM_WAIT || r2->call == SIMCALL_COMM_TEST)
125 && (simcall_comm_wait__get__comm(r1)->comm.src_proc == NULL
126 || simcall_comm_wait__get__comm(r1)->comm.dst_proc == NULL))
129 if (r2->call == SIMCALL_COMM_WAIT
130 && (r1->call == SIMCALL_COMM_WAIT || r1->call == SIMCALL_COMM_TEST)
131 && (simcall_comm_wait__get__comm(r2)->comm.src_proc == NULL
132 || simcall_comm_wait__get__comm(r2)->comm.dst_proc == NULL))
135 if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_WAIT
136 && simcall_comm_wait__get__comm(r1)->comm.src_buff ==
137 simcall_comm_wait__get__comm(r2)->comm.src_buff
138 && simcall_comm_wait__get__comm(r1)->comm.dst_buff ==
139 simcall_comm_wait__get__comm(r2)->comm.dst_buff)
142 if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_WAIT
143 && simcall_comm_wait__get__comm(r1)->comm.src_buff != NULL
144 && simcall_comm_wait__get__comm(r1)->comm.dst_buff != NULL
145 && simcall_comm_wait__get__comm(r2)->comm.src_buff != NULL
146 && simcall_comm_wait__get__comm(r2)->comm.dst_buff != NULL
147 && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
148 simcall_comm_wait__get__comm(r2)->comm.src_buff
149 && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
150 simcall_comm_wait__get__comm(r2)->comm.dst_buff
151 && simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
152 simcall_comm_wait__get__comm(r1)->comm.src_buff)
155 if (r1->call == SIMCALL_COMM_TEST &&
156 (simcall_comm_test__get__comm(r1) == NULL
157 || simcall_comm_test__get__comm(r1)->comm.src_buff == NULL
158 || simcall_comm_test__get__comm(r1)->comm.dst_buff == NULL))
161 if (r2->call == SIMCALL_COMM_TEST &&
162 (simcall_comm_test__get__comm(r2) == NULL
163 || simcall_comm_test__get__comm(r2)->comm.src_buff == NULL
164 || simcall_comm_test__get__comm(r2)->comm.dst_buff == NULL))
167 if (r1->call == SIMCALL_COMM_TEST && r2->call == SIMCALL_COMM_WAIT
168 && simcall_comm_test__get__comm(r1)->comm.src_buff ==
169 simcall_comm_wait__get__comm(r2)->comm.src_buff
170 && simcall_comm_test__get__comm(r1)->comm.dst_buff ==
171 simcall_comm_wait__get__comm(r2)->comm.dst_buff)
174 if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_TEST
175 && simcall_comm_wait__get__comm(r1)->comm.src_buff ==
176 simcall_comm_test__get__comm(r2)->comm.src_buff
177 && simcall_comm_wait__get__comm(r1)->comm.dst_buff ==
178 simcall_comm_test__get__comm(r2)->comm.dst_buff)
181 if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_TEST
182 && simcall_comm_wait__get__comm(r1)->comm.src_buff != NULL
183 && simcall_comm_wait__get__comm(r1)->comm.dst_buff != NULL
184 && simcall_comm_test__get__comm(r2)->comm.src_buff != NULL
185 && simcall_comm_test__get__comm(r2)->comm.dst_buff != NULL
186 && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
187 simcall_comm_test__get__comm(r2)->comm.src_buff
188 && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
189 simcall_comm_test__get__comm(r2)->comm.dst_buff
190 && simcall_comm_test__get__comm(r2)->comm.dst_buff !=
191 simcall_comm_wait__get__comm(r1)->comm.src_buff)
194 if (r1->call == SIMCALL_COMM_TEST && r2->call == SIMCALL_COMM_WAIT
195 && simcall_comm_test__get__comm(r1)->comm.src_buff != NULL
196 && simcall_comm_test__get__comm(r1)->comm.dst_buff != NULL
197 && simcall_comm_wait__get__comm(r2)->comm.src_buff != NULL
198 && simcall_comm_wait__get__comm(r2)->comm.dst_buff != NULL
199 && simcall_comm_test__get__comm(r1)->comm.dst_buff !=
200 simcall_comm_wait__get__comm(r2)->comm.src_buff
201 && simcall_comm_test__get__comm(r1)->comm.dst_buff !=
202 simcall_comm_wait__get__comm(r2)->comm.dst_buff
203 && simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
204 simcall_comm_test__get__comm(r1)->comm.src_buff)
211 static char *pointer_to_string(void *pointer)
214 if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
215 return bprintf("%p", pointer);
217 return xbt_strdup("(verbose only)");
220 static char *buff_size_to_string(size_t buff_size)
223 if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
224 return bprintf("%zu", buff_size);
226 return xbt_strdup("(verbose only)");
230 char *MC_request_to_string(smx_simcall_t req, int value)
232 char *type = NULL, *args = NULL, *str = NULL, *p = NULL, *bs = NULL;
233 smx_synchro_t act = NULL;
234 smx_mutex_t mutex = NULL;
238 case SIMCALL_COMM_ISEND:
239 type = xbt_strdup("iSend");
240 p = pointer_to_string(simcall_comm_isend__get__src_buff(req));
241 bs = buff_size_to_string(simcall_comm_isend__get__src_buff_size(req));
242 if (req->issuer->smx_host)
244 bprintf("src=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid,
245 MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
249 bprintf("src=(%lu)%s, buff=%s, size=%s", req->issuer->pid,
250 req->issuer->name, p, bs);
252 case SIMCALL_COMM_IRECV:
254 simcall_comm_irecv__get__dst_buff_size(req) ?
255 *simcall_comm_irecv__get__dst_buff_size(req) : 0;
256 type = xbt_strdup("iRecv");
257 p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req));
258 bs = buff_size_to_string(size);
259 if (req->issuer->smx_host)
261 bprintf("dst=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid,
262 MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
266 bprintf("dst=(%lu)%s, buff=%s, size=%s", req->issuer->pid,
267 req->issuer->name, p, bs);
269 case SIMCALL_COMM_WAIT:
270 act = simcall_comm_wait__get__comm(req);
272 type = xbt_strdup("WaitTimeout");
273 p = pointer_to_string(act);
274 args = bprintf("comm=%s", p);
276 type = xbt_strdup("Wait");
277 p = pointer_to_string(act);
278 args = bprintf("comm=%s [(%lu)%s (%s)-> (%lu)%s (%s)]", p,
279 act->comm.src_proc ? act->comm.src_proc->pid : 0,
280 act->comm.src_proc ? MSG_host_get_name(act->comm.src_proc->
282 act->comm.src_proc ? act->comm.src_proc->name : "",
283 act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
284 act->comm.dst_proc ? MSG_host_get_name(act->comm.dst_proc->
286 act->comm.dst_proc ? act->comm.dst_proc->name : "");
289 case SIMCALL_COMM_TEST:
290 act = simcall_comm_test__get__comm(req);
291 if (act->comm.src_proc == NULL || act->comm.dst_proc == NULL) {
292 type = xbt_strdup("Test FALSE");
293 p = pointer_to_string(act);
294 args = bprintf("comm=%s", p);
296 type = xbt_strdup("Test TRUE");
297 p = pointer_to_string(act);
298 args = bprintf("comm=%s [(%lu)%s (%s) -> (%lu)%s (%s)]", p,
299 act->comm.src_proc->pid, act->comm.src_proc->name,
300 MSG_host_get_name(act->comm.src_proc->smx_host),
301 act->comm.dst_proc->pid, act->comm.dst_proc->name,
302 MSG_host_get_name(act->comm.dst_proc->smx_host));
306 case SIMCALL_COMM_WAITANY:
307 type = xbt_strdup("WaitAny");
308 if (!xbt_dynar_is_empty(simcall_comm_waitany__get__comms(req))) {
309 p = pointer_to_string(xbt_dynar_get_as
310 (simcall_comm_waitany__get__comms(req), value,
313 bprintf("comm=%s (%d of %lu)", p, value + 1,
314 xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
316 args = bprintf("comm at idx %d", value);
320 case SIMCALL_COMM_TESTANY:
322 type = xbt_strdup("TestAny FALSE");
323 args = xbt_strdup("-");
325 type = xbt_strdup("TestAny");
327 bprintf("(%d of %lu)", value + 1,
328 xbt_dynar_length(simcall_comm_testany__get__comms(req)));
332 case SIMCALL_MUTEX_LOCK:
333 mutex = simcall_mutex_lock__get__mutex(req);
334 type = xbt_strdup("Mutex LOCK");
335 args = bprintf("locked = %d, owner = %d, sleeping = %d", mutex->locked, mutex->owner != NULL ? (int)mutex->owner->pid : -1, xbt_swag_size(mutex->sleeping));
338 case SIMCALL_MUTEX_UNLOCK:
339 type = xbt_strdup("Mutex UNLOCK");
340 mutex = simcall_mutex_unlock__get__mutex(req);
341 args = bprintf("locked = %d, owner = %d, sleeping = %d", mutex->locked, mutex->owner != NULL ? (int)mutex->owner->pid : -1, xbt_swag_size(mutex->sleeping));
344 case SIMCALL_MC_SNAPSHOT:
345 type = xbt_strdup("MC_SNAPSHOT");
349 case SIMCALL_MC_COMPARE_SNAPSHOTS:
350 type = xbt_strdup("MC_COMPARE_SNAPSHOTS");
354 case SIMCALL_MC_RANDOM:
355 type = xbt_strdup("MC_RANDOM");
356 args = bprintf("%d", value);
365 bprintf("[(%lu)%s (%s)] %s(%s)", req->issuer->pid,
366 MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
370 bprintf("[(%lu)%s (%s)] %s ", req->issuer->pid,
371 MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
382 unsigned int MC_request_testany_fail(smx_simcall_t req)
385 smx_synchro_t action;
387 xbt_dynar_foreach(simcall_comm_testany__get__comms(req), cursor, action) {
388 if (action->comm.src_proc && action->comm.dst_proc)
395 int MC_request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx)
401 case SIMCALL_COMM_WAIT:
402 /* FIXME: check also that src and dst processes are not suspended */
403 act = simcall_comm_wait__get__comm(req);
404 return (act->comm.src_proc && act->comm.dst_proc);
407 case SIMCALL_COMM_WAITANY:
409 xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), idx,
411 return (act->comm.src_proc && act->comm.dst_proc);
414 case SIMCALL_COMM_TESTANY:
416 xbt_dynar_get_as(simcall_comm_testany__get__comms(req), idx,
418 return (act->comm.src_proc && act->comm.dst_proc);
426 int MC_process_is_enabled(smx_process_t process)
428 return MC_request_is_enabled(&process->simcall);
431 char *MC_request_get_dot_output(smx_simcall_t req, int value)
434 char *str = NULL, *label = NULL;
435 smx_synchro_t act = NULL;
438 case SIMCALL_COMM_ISEND:
439 if (req->issuer->smx_host)
441 bprintf("[(%lu)%s] iSend", req->issuer->pid,
442 MSG_host_get_name(req->issuer->smx_host));
444 label = bprintf("[(%lu)] iSend", req->issuer->pid);
447 case SIMCALL_COMM_IRECV:
448 if (req->issuer->smx_host)
450 bprintf("[(%lu)%s] iRecv", req->issuer->pid,
451 MSG_host_get_name(req->issuer->smx_host));
453 label = bprintf("[(%lu)] iRecv", req->issuer->pid);
456 case SIMCALL_COMM_WAIT:
457 act = simcall_comm_wait__get__comm(req);
459 if (req->issuer->smx_host)
461 bprintf("[(%lu)%s] WaitTimeout", req->issuer->pid,
462 MSG_host_get_name(req->issuer->smx_host));
464 label = bprintf("[(%lu)] WaitTimeout", req->issuer->pid);
466 if (req->issuer->smx_host)
468 bprintf("[(%lu)%s] Wait [(%lu)->(%lu)]", req->issuer->pid,
469 MSG_host_get_name(req->issuer->smx_host),
470 act->comm.src_proc ? act->comm.src_proc->pid : 0,
471 act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
474 bprintf("[(%lu)] Wait [(%lu)->(%lu)]", req->issuer->pid,
475 act->comm.src_proc ? act->comm.src_proc->pid : 0,
476 act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
480 case SIMCALL_COMM_TEST:
481 act = simcall_comm_test__get__comm(req);
482 if (act->comm.src_proc == NULL || act->comm.dst_proc == NULL) {
483 if (req->issuer->smx_host)
485 bprintf("[(%lu)%s] Test FALSE", req->issuer->pid,
486 MSG_host_get_name(req->issuer->smx_host));
488 label = bprintf("[(%lu)] Test FALSE", req->issuer->pid);
490 if (req->issuer->smx_host)
492 bprintf("[(%lu)%s] Test TRUE", req->issuer->pid,
493 MSG_host_get_name(req->issuer->smx_host));
495 label = bprintf("[(%lu)] Test TRUE", req->issuer->pid);
499 case SIMCALL_COMM_WAITANY:
500 if (req->issuer->smx_host)
502 bprintf("[(%lu)%s] WaitAny [%d of %lu]", req->issuer->pid,
503 MSG_host_get_name(req->issuer->smx_host), value + 1,
504 xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
507 bprintf("[(%lu)] WaitAny [%d of %lu]", req->issuer->pid, value + 1,
508 xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
511 case SIMCALL_COMM_TESTANY:
513 if (req->issuer->smx_host)
515 bprintf("[(%lu)%s] TestAny FALSE", req->issuer->pid,
516 MSG_host_get_name(req->issuer->smx_host));
518 label = bprintf("[(%lu)] TestAny FALSE", req->issuer->pid);
520 if (req->issuer->smx_host)
522 bprintf("[(%lu)%s] TestAny TRUE [%d of %lu]", req->issuer->pid,
523 MSG_host_get_name(req->issuer->smx_host), value + 1,
524 xbt_dynar_length(simcall_comm_testany__get__comms(req)));
527 bprintf("[(%lu)] TestAny TRUE [%d of %lu]", req->issuer->pid,
529 xbt_dynar_length(simcall_comm_testany__get__comms(req)));
533 case SIMCALL_MUTEX_LOCK:
534 label = bprintf("[(%lu)] Mutex LOCK", req->issuer->pid);
537 case SIMCALL_MUTEX_UNLOCK:
538 label = bprintf("[(%lu)] Mutex UNLOCK", req->issuer->pid);
541 case SIMCALL_MC_RANDOM:
542 if (req->issuer->smx_host)
544 bprintf("[(%lu)%s] MC_RANDOM (%d)", req->issuer->pid,
545 MSG_host_get_name(req->issuer->smx_host), value);
547 label = bprintf("[(%lu)] MC_RANDOM (%d)", req->issuer->pid, value);
550 case SIMCALL_MC_SNAPSHOT:
551 if (req->issuer->smx_host)
553 bprintf("[(%lu)%s] MC_SNAPSHOT", req->issuer->pid,
554 MSG_host_get_name(req->issuer->smx_host));
556 label = bprintf("[(%lu)] MC_SNAPSHOT", req->issuer->pid);
559 case SIMCALL_MC_COMPARE_SNAPSHOTS:
560 if (req->issuer->smx_host)
562 bprintf("[(%lu)%s] MC_COMPARE_SNAPSHOTS", req->issuer->pid,
563 MSG_host_get_name(req->issuer->smx_host));
565 label = bprintf("[(%lu)] MC_COMPARE_SNAPSHOTS", req->issuer->pid);
573 bprintf("label = \"%s\", color = %s, fontcolor = %s", label,
574 colors[req->issuer->pid - 1], colors[req->issuer->pid - 1]);