Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c10b1921948cdbb194386ec6b0316460ad1e57b5
[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   /* FIXME: the following rule assumes that the result of the
15    * isend/irecv call is not stored in a buffer used in the
16    * wait/test call.
17   if(   (r1->call == REQ_COMM_ISEND || r1->call == REQ_COMM_IRECV)
18      && (r2->call == REQ_COMM_WAIT || r2->call == REQ_COMM_TEST))
19     return FALSE;*/
20
21   /* FIXME: the following rule assumes that the result of the
22    * isend/irecv call is not stored in a buffer used in the
23    * wait/test call.
24   if(   (r2->call == REQ_COMM_ISEND || r2->call == REQ_COMM_IRECV)
25      && (r1->call == REQ_COMM_WAIT || r1->call == REQ_COMM_TEST))
26     return FALSE;*/
27
28   if(r1->call == REQ_COMM_ISEND && r2->call == REQ_COMM_ISEND
29       && r1->comm_isend.rdv != r2->comm_isend.rdv)
30     return FALSE;
31
32   if(r1->call == REQ_COMM_IRECV && r2->call == REQ_COMM_IRECV
33       && r1->comm_irecv.rdv != r2->comm_irecv.rdv)
34     return FALSE;
35
36   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
37       && r1->comm_wait.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
38       && r1->comm_wait.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
39     return FALSE;
40
41   if (r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_WAIT
42       && r1->comm_wait.comm->comm.src_buff != NULL
43       && r1->comm_wait.comm->comm.dst_buff != NULL
44       && r2->comm_wait.comm->comm.src_buff != NULL
45       && r2->comm_wait.comm->comm.dst_buff != NULL
46       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.src_buff
47       && r1->comm_wait.comm->comm.dst_buff != r2->comm_wait.comm->comm.dst_buff
48       && r2->comm_wait.comm->comm.dst_buff != r1->comm_wait.comm->comm.src_buff)
49     return FALSE;
50
51   if(r1->call == REQ_COMM_TEST &&
52       (r1->comm_test.comm == NULL
53        || r1->comm_test.comm->comm.src_buff == NULL
54        || r1->comm_test.comm->comm.dst_buff == NULL))
55     return FALSE;
56
57   if(r2->call == REQ_COMM_TEST &&
58       (r2->comm_test.comm == NULL
59        || r2->comm_test.comm->comm.src_buff == NULL
60        || r2->comm_test.comm->comm.dst_buff == NULL))
61     return FALSE;
62
63   if(r1->call == REQ_COMM_TEST && r2->call == REQ_COMM_WAIT
64       && r1->comm_test.comm->comm.src_buff == r2->comm_wait.comm->comm.src_buff
65       && r1->comm_test.comm->comm.dst_buff == r2->comm_wait.comm->comm.dst_buff)
66     return FALSE;
67
68   if(r1->call == REQ_COMM_WAIT && r2->call == REQ_COMM_TEST
69       && r1->comm_wait.comm->comm.src_buff == r2->comm_test.comm->comm.src_buff
70       && r1->comm_wait.comm->comm.dst_buff == r2->comm_test.comm->comm.dst_buff)
71     return FALSE;
72
73   return TRUE;
74 }
75
76 char *MC_request_to_string(smx_req_t req)
77 {
78   char *type = NULL, *args = NULL, *str = NULL; 
79   smx_action_t act = NULL;
80   size_t size = 0;
81   
82   switch(req->call){
83     case REQ_COMM_ISEND:
84       type = bprintf("iSend");
85       args = bprintf("src=%s, buff=%p, size=%zu", req->issuer->name, 
86                      req->comm_isend.src_buff, req->comm_isend.src_buff_size);
87       break;
88     case REQ_COMM_IRECV:
89       size = req->comm_irecv.dst_buff_size ? *req->comm_irecv.dst_buff_size : 0;
90       type = bprintf("iRecv");
91       args = bprintf("dst=%s, buff=%p, size=%zu", req->issuer->name, 
92                      req->comm_irecv.dst_buff, size);
93       break;
94     case REQ_COMM_WAIT:
95       act = req->comm_wait.comm;
96       type = bprintf("Wait");
97       args  = bprintf("comm=%p [%s(%lu) -> %s(%lu)]", act,
98                       act->comm.src_proc ? act->comm.src_proc->name : "",
99                       act->comm.src_proc ? act->comm.src_proc->pid : 0,
100                       act->comm.dst_proc ? act->comm.dst_proc->name : "",
101                       act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
102       break;
103     case REQ_COMM_TEST:
104       act = req->comm_test.comm;
105       type = bprintf("Test");
106       args  = bprintf("comm=%p [%s -> %s]", act,
107                       act->comm.src_proc ? act->comm.src_proc->name : "",
108                       act->comm.dst_proc ? act->comm.dst_proc->name : "");
109       break;
110
111     case REQ_COMM_WAITANY:
112       type = bprintf("WaitAny");
113       args = bprintf("-");
114       /* FIXME: improve output */
115       break;
116
117     case REQ_COMM_TESTANY:
118        type = bprintf("TestAny");
119        args = bprintf("-");
120        /* FIXME: improve output */
121        break;
122
123     default:
124       THROW_UNIMPLEMENTED;
125   }
126
127   str = bprintf("[(%lu)%s] %s (%s)", req->issuer->pid ,req->issuer->name, type, args);
128   xbt_free(type);
129   xbt_free(args);
130   return str;
131 }
132
133 unsigned int MC_request_testany_fail(smx_req_t req)
134 {
135   unsigned int cursor;
136   smx_action_t action;
137
138   xbt_dynar_foreach(req->comm_testany.comms, cursor, action){
139     if(action->comm.src_proc && action->comm.dst_proc)
140       return FALSE;
141   }
142
143   return TRUE;
144 }
145
146 int MC_request_is_visible(smx_req_t req)
147 {
148   return req->call == REQ_COMM_ISEND
149      || req->call == REQ_COMM_IRECV
150      || req->call == REQ_COMM_WAIT
151      || req->call == REQ_COMM_WAITANY
152      || req->call == REQ_COMM_TEST
153      || req->call == REQ_COMM_TESTANY;
154 }
155
156 int MC_request_is_enabled(smx_req_t req)
157 {
158   unsigned int index = 0;
159   smx_action_t act;
160
161   switch (req->call) {
162
163     case REQ_COMM_WAIT:
164       /* FIXME: check also that src and dst processes are not suspended */
165
166       /* If it has a timeout it will be always be enabled, because even if the
167        * communication is not ready, it can timeout and won't block.
168        * On the other hand if it hasn't a timeout, check if the comm is ready.*/
169       if(req->comm_wait.timeout >= 0){
170         return TRUE;
171       }else{
172         act = req->comm_wait.comm;
173         return (act->comm.src_proc && act->comm.dst_proc);
174       }
175       break;
176
177     case REQ_COMM_WAITANY:
178       /* Check if it has at least one communication ready */
179       xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
180         if (act->comm.src_proc && act->comm.dst_proc){
181           return TRUE;
182         }
183       }
184       return FALSE;
185       break;
186
187     default:
188       /* The rest of the request are always enabled */
189       return TRUE;
190   }
191 }
192
193 int MC_request_is_enabled_by_idx(smx_req_t req, unsigned int idx)
194 {
195   smx_action_t act;
196
197   switch (req->call) {
198
199     case REQ_COMM_WAIT:
200       /* FIXME: check also that src and dst processes are not suspended */
201       act = req->comm_wait.comm;
202       return (act->comm.src_proc && act->comm.dst_proc);
203       break;
204
205     case REQ_COMM_WAITANY:
206       act = xbt_dynar_get_as(req->comm_waitany.comms, idx, smx_action_t);
207       return (act->comm.src_proc && act->comm.dst_proc);
208       break;
209
210     default:
211       return TRUE;
212   }
213 }
214
215 int MC_process_is_enabled(smx_process_t process)
216 {
217   if (process->request.call != REQ_NO_REQ && MC_request_is_enabled(&process->request))
218     return TRUE;
219
220   return FALSE;
221 }