Logo AND Algorithmique Numérique Distribuée

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