Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[trace] adding a new boolean parameter (tracing/platform) to register platform in...
[simgrid.git] / src / mc / mc_request.c
1 #include "private.h"
2
3 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc,
4                                 "Logging specific to MC (request)");
5
6 static char* pointer_to_string(void* pointer);
7 static char* buff_size_to_string(size_t size);
8
9 int MC_request_depend(smx_req_t r1, smx_req_t r2)
10 {
11   if(_surf_do_model_check == 2)
12     return TRUE;
13
14   if (r1->issuer == r2->issuer)
15     return FALSE;
16
17   if(r1->call == REQ_COMM_ISEND && r2->call == REQ_COMM_IRECV)
18     return FALSE;
19
20   if(r1->call == REQ_COMM_IRECV && r2->call == REQ_COMM_ISEND)
21     return FALSE;
22
23   if(   (r1->call == REQ_COMM_ISEND || r1->call == REQ_COMM_IRECV)
24        &&  r2->call == REQ_COMM_WAIT){
25
26     if(r2->comm_wait.comm->comm.rdv == NULL)
27       return FALSE;
28
29     smx_rdv_t rdv = r1->call == REQ_COMM_ISEND ? r1->comm_isend.rdv : r1->comm_irecv.rdv;
30
31     if(r2->comm_wait.comm->comm.rdv != rdv)
32       return FALSE;
33
34     if(r2->comm_wait.comm->comm.type == SIMIX_COMM_SEND && r1->call == REQ_COMM_ISEND)
35       return FALSE;
36
37     if(r2->comm_wait.comm->comm.type == SIMIX_COMM_RECEIVE && r1->call == REQ_COMM_IRECV)
38       return FALSE;
39   }
40
41   if(   (r2->call == REQ_COMM_ISEND || r2->call == REQ_COMM_IRECV)
42        &&  r1->call == REQ_COMM_WAIT){
43
44     if(r1->comm_wait.comm->comm.rdv != NULL)
45       return FALSE;
46
47     smx_rdv_t rdv = r2->call == REQ_COMM_ISEND ? r2->comm_isend.rdv : r2->comm_irecv.rdv;
48
49     if(r1->comm_wait.comm->comm.rdv != rdv)
50       return FALSE;
51
52     if(r1->comm_wait.comm->comm.type == SIMIX_COMM_SEND && r2->call == REQ_COMM_ISEND)
53       return FALSE;
54
55     if(r1->comm_wait.comm->comm.type == SIMIX_COMM_RECEIVE && r2->call == REQ_COMM_IRECV)
56       return FALSE;
57   }
58
59   /* FIXME: the following rule assumes that the result of the
60    * isend/irecv call is not stored in a buffer used in the
61    * test call. */
62   if(   (r1->call == REQ_COMM_ISEND || r1->call == REQ_COMM_IRECV)
63      &&  r2->call == REQ_COMM_TEST)
64     return FALSE;
65
66   /* FIXME: the following rule assumes that the result of the
67    * isend/irecv call is not stored in a buffer used in the
68    * test call.*/
69   if(   (r2->call == REQ_COMM_ISEND || r2->call == REQ_COMM_IRECV)
70      && r1->call == REQ_COMM_TEST)
71     return FALSE;
72
73   if(r1->call == REQ_COMM_ISEND && r2->call == REQ_COMM_ISEND
74       && r1->comm_isend.rdv != r2->comm_isend.rdv)
75     return FALSE;
76
77   if(r1->call == REQ_COMM_IRECV && r2->call == REQ_COMM_IRECV
78       && r1->comm_irecv.rdv != r2->comm_irecv.rdv)
79     return FALSE;
80
81   if(r1->call == REQ_COMM_WAIT && (r2->call == REQ_COMM_WAIT || r2->call == REQ_COMM_TEST)
82      && (r1->comm_wait.comm->comm.src_proc == NULL
83          || r1->comm_wait.comm->comm.dst_proc == NULL))
84     return FALSE;
85
86   if(r2->call == REQ_COMM_WAIT && (r1->call == REQ_COMM_WAIT || r1->call == REQ_COMM_TEST)
87      && (r2->comm_wait.comm->comm.src_proc == NULL
88          || r2->comm_wait.comm->comm.dst_proc == NULL))
89     return FALSE;
90
91   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
92       && r1->comm_wait.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
93       && r1->comm_wait.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
94     return FALSE;
95
96   if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
97       && r1->comm_wait.comm->comm.src_buff != NULL
98       && r1->comm_wait.comm->comm.dst_buff != NULL
99       && r2->comm_wait.comm->comm.src_buff != NULL
100       && r2->comm_wait.comm->comm.dst_buff != NULL
101       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
102       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
103       && r2->comm_wait.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
104     return FALSE;
105
106   if(r1->call == REQ_COMM_TEST &&
107       (r1->comm_test.comm == NULL
108        || r1->comm_test.comm->comm.src_buff == NULL
109        || r1->comm_test.comm->comm.dst_buff == NULL))
110     return FALSE;
111
112   if(r2->call == REQ_COMM_TEST &&
113       (r2->comm_test.comm == NULL
114        || r2->comm_test.comm->comm.src_buff == NULL
115        || r2->comm_test.comm->comm.dst_buff == NULL))
116     return FALSE;
117
118   if(r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
119       && r1->comm_test.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
120       && r1->comm_test.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
121     return FALSE;
122
123   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
124       && r1->comm_wait.comm->comm.src_buff == r2->comm_test.comm->comm.src_buff
125       && r1->comm_wait.comm->comm.dst_buff == r2->comm_test.comm->comm.dst_buff)
126     return FALSE;
127
128   if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
129         && r1->comm_wait.comm->comm.src_buff != NULL
130         && r1->comm_wait.comm->comm.dst_buff != NULL
131         && r2->comm_test.comm->comm.src_buff != NULL
132         && r2->comm_test.comm->comm.dst_buff != NULL
133         && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.src_buff
134         && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.dst_buff
135         && r2->comm_test.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
136     return FALSE;
137
138   if (r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
139           && r1->comm_test.comm->comm.src_buff != NULL
140           && r1->comm_test.comm->comm.dst_buff != NULL
141           && r2->comm_wait.comm->comm.src_buff != NULL
142           && r2->comm_wait.comm->comm.dst_buff != NULL
143           && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
144           && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
145           && r2->comm_wait.comm->comm.dst_buff != r1->comm_test.comm->comm.src_buff)
146       return FALSE;
147
148   return TRUE;
149 }
150
151 static char* pointer_to_string(void* pointer) {
152
153   if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
154     return bprintf("%p", pointer);
155
156   return xbt_strdup("(verbose only)");
157 }
158
159 static char* buff_size_to_string(size_t buff_size) {
160
161   if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
162     return bprintf("%zu", buff_size);
163
164   return xbt_strdup("(verbose only)");
165 }
166
167
168 char *MC_request_to_string(smx_req_t req, int value)
169 {
170   char *type = NULL, *args = NULL, *str = NULL, *p = NULL, *bs = NULL;
171   smx_action_t act = NULL;
172   size_t size = 0;
173
174   switch(req->call){
175     case REQ_COMM_ISEND:
176       type = xbt_strdup("iSend");
177       p = pointer_to_string(req->comm_isend.src_buff);
178       bs = buff_size_to_string(req->comm_isend.src_buff_size);
179       args = bprintf("src=%s, buff=%s, size=%s", req->issuer->name, p, bs);
180       break;
181     case REQ_COMM_IRECV:
182       size = req->comm_irecv.dst_buff_size ? *req->comm_irecv.dst_buff_size : 0;
183       type = xbt_strdup("iRecv");
184       p = pointer_to_string(req->comm_irecv.dst_buff); 
185       bs = buff_size_to_string(size);
186       args = bprintf("dst=%s, buff=%s, size=%s", req->issuer->name, p, bs);
187       break;
188     case REQ_COMM_WAIT:
189       act = req->comm_wait.comm;
190       if(value == -1){
191         type = xbt_strdup("WaitTimeout");
192         p = pointer_to_string(act);
193         args = bprintf("comm=%p", p);
194       }else{
195         type = xbt_strdup("Wait");
196         p = pointer_to_string(act);
197         args  = bprintf("comm=%s [(%lu)%s -> (%lu)%s]", p,
198                         act->comm.src_proc ? act->comm.src_proc->pid : 0,
199                         act->comm.src_proc ? act->comm.src_proc->name : "",
200                         act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
201                         act->comm.dst_proc ? act->comm.dst_proc->name : "");
202       }
203       break;
204     case REQ_COMM_TEST:
205       act = req->comm_test.comm;
206       if(act->comm.src_proc == NULL || act->comm.src_proc == NULL){
207         type = xbt_strdup("Test FALSE");
208         p = pointer_to_string(act);
209         args = bprintf("comm=%s", p);
210       }else{
211         type = xbt_strdup("Test TRUE");
212         p = pointer_to_string(act);
213         args  = bprintf("comm=%s [(%lu)%s -> (%lu)%s]", p,
214                         act->comm.src_proc ? act->comm.src_proc->pid : 0,
215                         act->comm.src_proc ? act->comm.src_proc->name : "",
216                         act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
217                         act->comm.dst_proc ? act->comm.dst_proc->name : "");
218       }
219       break;
220
221     case REQ_COMM_WAITANY:
222       type = xbt_strdup("WaitAny");
223       p = pointer_to_string(xbt_dynar_get_as(req->comm_waitany.comms, value, smx_action_t));
224       args = bprintf("comm=%s (%d of %lu)", p,
225                      value+1, xbt_dynar_length(req->comm_waitany.comms));
226       break;
227
228     case REQ_COMM_TESTANY:
229       if(value == -1){
230         type = xbt_strdup("TestAny FALSE");
231         args = xbt_strdup("-");
232       }else{
233         type = xbt_strdup("TestAny");
234         args = bprintf("(%d of %lu)", value+1, xbt_dynar_length(req->comm_testany.comms));
235       }
236       break;
237
238     default:
239       THROW_UNIMPLEMENTED;
240   }
241
242   str = bprintf("[(%lu)%s] %s (%s)", req->issuer->pid ,req->issuer->name, type, args);
243   xbt_free(type);
244   xbt_free(args);
245   xbt_free(p);
246   xbt_free(bs);
247   return str;
248 }
249
250 unsigned int MC_request_testany_fail(smx_req_t req)
251 {
252   unsigned int cursor;
253   smx_action_t action;
254
255   xbt_dynar_foreach(req->comm_testany.comms, cursor, action){
256     if(action->comm.src_proc && action->comm.dst_proc)
257       return FALSE;
258   }
259
260   return TRUE;
261 }
262
263 int MC_request_is_visible(smx_req_t req)
264 {
265   return req->call == REQ_COMM_ISEND
266      || req->call == REQ_COMM_IRECV
267      || req->call == REQ_COMM_WAIT
268      || req->call == REQ_COMM_WAITANY
269      || req->call == REQ_COMM_TEST
270      || req->call == REQ_COMM_TESTANY;
271 }
272
273 int MC_request_is_enabled(smx_req_t req)
274 {
275   unsigned int index = 0;
276   smx_action_t act;
277
278   switch (req->call) {
279
280     case REQ_COMM_WAIT:
281       /* FIXME: check also that src and dst processes are not suspended */
282
283       /* If it has a timeout it will be always be enabled, because even if the
284        * communication is not ready, it can timeout and won't block.
285        * On the other hand if it hasn't a timeout, check if the comm is ready.*/
286       if(req->comm_wait.timeout >= 0){
287         return TRUE;
288       }else{
289         act = req->comm_wait.comm;
290         return (act->comm.src_proc && act->comm.dst_proc);
291       }
292       break;
293
294     case REQ_COMM_WAITANY:
295       /* Check if it has at least one communication ready */
296       xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
297         if (act->comm.src_proc && act->comm.dst_proc){
298           return TRUE;
299         }
300       }
301       return FALSE;
302       break;
303
304     default:
305       /* The rest of the request are always enabled */
306       return TRUE;
307   }
308 }
309
310 int MC_request_is_enabled_by_idx(smx_req_t req, unsigned int idx)
311 {
312   smx_action_t act;
313
314   switch (req->call) {
315
316     case REQ_COMM_WAIT:
317       /* FIXME: check also that src and dst processes are not suspended */
318       act = req->comm_wait.comm;
319       return (act->comm.src_proc && act->comm.dst_proc);
320       break;
321
322     case REQ_COMM_WAITANY:
323       act = xbt_dynar_get_as(req->comm_waitany.comms, idx, smx_action_t);
324       return (act->comm.src_proc && act->comm.dst_proc);
325       break;
326
327     case REQ_COMM_TESTANY:
328       act = xbt_dynar_get_as(req->comm_testany.comms, idx, smx_action_t);
329       return (act->comm.src_proc && act->comm.dst_proc);
330       break;
331
332     default:
333       return TRUE;
334   }
335 }
336
337 int MC_process_is_enabled(smx_process_t process)
338 {
339   if (process->request.call != REQ_NO_REQ && MC_request_is_enabled(&process->request))
340     return TRUE;
341
342   return FALSE;
343 }