Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
It does not work on apple to.
[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(r1->call == REQ_COMM_WAIT && (r2->call == REQ_COMM_WAIT || r2->call == REQ_COMM_TEST)
73      && (r1->comm_wait.comm->comm.src_proc == NULL
74          || r1->comm_wait.comm->comm.dst_proc == NULL))
75     return FALSE;
76
77   if(r2->call == REQ_COMM_WAIT && (r1->call == REQ_COMM_WAIT || r1->call == REQ_COMM_TEST)
78      && (r2->comm_wait.comm->comm.src_proc == NULL
79          || r2->comm_wait.comm->comm.dst_proc == NULL))
80     return FALSE;
81
82   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
83       && r1->comm_wait.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
84       && r1->comm_wait.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
85     return FALSE;
86
87   if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
88       && r1->comm_wait.comm->comm.src_buff != NULL
89       && r1->comm_wait.comm->comm.dst_buff != NULL
90       && r2->comm_wait.comm->comm.src_buff != NULL
91       && r2->comm_wait.comm->comm.dst_buff != NULL
92       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
93       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
94       && r2->comm_wait.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
95     return FALSE;
96
97   if(r1->call == REQ_COMM_TEST &&
98       (r1->comm_test.comm == NULL
99        || r1->comm_test.comm->comm.src_buff == NULL
100        || r1->comm_test.comm->comm.dst_buff == NULL))
101     return FALSE;
102
103   if(r2->call == REQ_COMM_TEST &&
104       (r2->comm_test.comm == NULL
105        || r2->comm_test.comm->comm.src_buff == NULL
106        || r2->comm_test.comm->comm.dst_buff == NULL))
107     return FALSE;
108
109   if(r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
110       && r1->comm_test.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
111       && r1->comm_test.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
112     return FALSE;
113
114   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
115       && r1->comm_wait.comm->comm.src_buff == r2->comm_test.comm->comm.src_buff
116       && r1->comm_wait.comm->comm.dst_buff == r2->comm_test.comm->comm.dst_buff)
117     return FALSE;
118
119   if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
120         && r1->comm_wait.comm->comm.src_buff != NULL
121         && r1->comm_wait.comm->comm.dst_buff != NULL
122         && r2->comm_test.comm->comm.src_buff != NULL
123         && r2->comm_test.comm->comm.dst_buff != NULL
124         && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.src_buff
125         && r1->comm_wait.comm->comm.dst_buff != r2->comm_test.comm->comm.dst_buff
126         && r2->comm_test.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
127     return FALSE;
128
129   if (r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
130           && r1->comm_test.comm->comm.src_buff != NULL
131           && r1->comm_test.comm->comm.dst_buff != NULL
132           && r2->comm_wait.comm->comm.src_buff != NULL
133           && r2->comm_wait.comm->comm.dst_buff != NULL
134           && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
135           && r1->comm_test.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
136           && r2->comm_wait.comm->comm.dst_buff != r1->comm_test.comm->comm.src_buff)
137       return FALSE;
138
139   return TRUE;
140 }
141
142 char *MC_request_to_string(smx_req_t req, int value)
143 {
144   char *type = NULL, *args = NULL, *str = NULL; 
145   smx_action_t act = NULL;
146   size_t size = 0;
147   
148   switch(req->call){
149     case REQ_COMM_ISEND:
150       type = bprintf("iSend");
151       args = bprintf("src=%s, buff=%p, size=%zu", req->issuer->name, 
152                      req->comm_isend.src_buff, req->comm_isend.src_buff_size);
153       break;
154     case REQ_COMM_IRECV:
155       size = req->comm_irecv.dst_buff_size ? *req->comm_irecv.dst_buff_size : 0;
156       type = bprintf("iRecv");
157       args = bprintf("dst=%s, buff=%p, size=%zu", req->issuer->name, 
158                      req->comm_irecv.dst_buff, size);
159       break;
160     case REQ_COMM_WAIT:
161       act = req->comm_wait.comm;
162       if(value == -1){
163         type = bprintf("WaitTimeout");
164         args = bprintf("comm=%p", act);
165       }else{
166         type = bprintf("Wait");
167         args  = bprintf("comm=%p [(%lu)%s -> (%lu)%s]", act,
168                         act->comm.src_proc ? act->comm.src_proc->pid : 0,
169                         act->comm.src_proc ? act->comm.src_proc->name : "",
170                         act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
171                         act->comm.dst_proc ? act->comm.dst_proc->name : "");
172       }
173       break;
174     case REQ_COMM_TEST:
175       act = req->comm_test.comm;
176       if(act->comm.src_proc == NULL || act->comm.src_proc == NULL){
177         type = bprintf("Test FALSE");
178         args = bprintf("comm=%p", act);
179       }else{
180         type = bprintf("Test TRUE");
181         args  = bprintf("comm=%p [(%lu)%s -> (%lu)%s]", act,
182                           act->comm.src_proc ? act->comm.src_proc->pid : 0,
183                           act->comm.src_proc ? act->comm.src_proc->name : "",
184                           act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
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("comm=%p (%d of %lu)", xbt_dynar_get_as(req->comm_waitany.comms, value, smx_action_t),
192                      value+1, xbt_dynar_length(req->comm_waitany.comms));
193       break;
194
195     case REQ_COMM_TESTANY:
196       if(value == -1){
197         type = bprintf("TestAny FALSE");
198         args = bprintf("-");
199       }else{
200         type = bprintf("TestAny");
201         args = bprintf("(%d of %lu)", value+1, xbt_dynar_length(req->comm_testany.comms));
202       }
203       break;
204
205     default:
206       THROW_UNIMPLEMENTED;
207   }
208
209   str = bprintf("[(%lu)%s] %s (%s)", req->issuer->pid ,req->issuer->name, type, args);
210   xbt_free(type);
211   xbt_free(args);
212   return str;
213 }
214
215 unsigned int MC_request_testany_fail(smx_req_t req)
216 {
217   unsigned int cursor;
218   smx_action_t action;
219
220   xbt_dynar_foreach(req->comm_testany.comms, cursor, action){
221     if(action->comm.src_proc && action->comm.dst_proc)
222       return FALSE;
223   }
224
225   return TRUE;
226 }
227
228 int MC_request_is_visible(smx_req_t req)
229 {
230   return req->call == REQ_COMM_ISEND
231      || req->call == REQ_COMM_IRECV
232      || req->call == REQ_COMM_WAIT
233      || req->call == REQ_COMM_WAITANY
234      || req->call == REQ_COMM_TEST
235      || req->call == REQ_COMM_TESTANY;
236 }
237
238 int MC_request_is_enabled(smx_req_t req)
239 {
240   unsigned int index = 0;
241   smx_action_t act;
242
243   switch (req->call) {
244
245     case REQ_COMM_WAIT:
246       /* FIXME: check also that src and dst processes are not suspended */
247
248       /* If it has a timeout it will be always be enabled, because even if the
249        * communication is not ready, it can timeout and won't block.
250        * On the other hand if it hasn't a timeout, check if the comm is ready.*/
251       if(req->comm_wait.timeout >= 0){
252         return TRUE;
253       }else{
254         act = req->comm_wait.comm;
255         return (act->comm.src_proc && act->comm.dst_proc);
256       }
257       break;
258
259     case REQ_COMM_WAITANY:
260       /* Check if it has at least one communication ready */
261       xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
262         if (act->comm.src_proc && act->comm.dst_proc){
263           return TRUE;
264         }
265       }
266       return FALSE;
267       break;
268
269     default:
270       /* The rest of the request are always enabled */
271       return TRUE;
272   }
273 }
274
275 int MC_request_is_enabled_by_idx(smx_req_t req, unsigned int idx)
276 {
277   smx_action_t act;
278
279   switch (req->call) {
280
281     case REQ_COMM_WAIT:
282       /* FIXME: check also that src and dst processes are not suspended */
283       act = req->comm_wait.comm;
284       return (act->comm.src_proc && act->comm.dst_proc);
285       break;
286
287     case REQ_COMM_WAITANY:
288       act = xbt_dynar_get_as(req->comm_waitany.comms, idx, smx_action_t);
289       return (act->comm.src_proc && act->comm.dst_proc);
290       break;
291
292     case REQ_COMM_TESTANY:
293       act = xbt_dynar_get_as(req->comm_testany.comms, idx, smx_action_t);
294       return (act->comm.src_proc && act->comm.dst_proc);
295       break;
296
297     default:
298       return TRUE;
299   }
300 }
301
302 int MC_process_is_enabled(smx_process_t process)
303 {
304   if (process->request.call != REQ_NO_REQ && MC_request_is_enabled(&process->request))
305     return TRUE;
306
307   return FALSE;
308 }