Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c6c278a7626d0666ec0a25b4180f01166800c0ec
[simgrid.git] / src / simix / smx_smurf.c
1 #include "private.h"
2 #include "xbt/fifo.h"
3 #include "xbt/xbt_os_thread.h"
4
5 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_smurf, simix,
6                                 "Logging specific to SIMIX (SMURF)");
7
8 static xbt_dynar_t req_vector;
9 static xbt_os_mutex_t sync_req_vector;
10
11 void SIMIX_request_init(void)
12 {
13   sync_req_vector = xbt_os_mutex_init();
14   req_vector = xbt_dynar_new(sizeof(void *), NULL);
15 }
16
17 void SIMIX_request_destroy(void)
18 {
19   xbt_os_mutex_destroy(sync_req_vector);
20   xbt_dynar_free(&req_vector);
21 }
22
23 void SIMIX_request_push(smx_req_t req)
24 {
25   req->issuer = SIMIX_process_self();
26   if(req->issuer != simix_global->maestro_process){
27     xbt_os_mutex_acquire(sync_req_vector);
28     xbt_dynar_set_as(req_vector, req->issuer->pid, smx_req_t, req);
29     xbt_os_mutex_release(sync_req_vector);
30     req->issuer->request = req;
31     DEBUG2("Yield process '%s' on request of type %d", req->issuer->name, req->call);
32     SIMIX_process_yield();
33   }else{
34     SIMIX_request_pre(req);
35   }
36 }
37
38 smx_req_t SIMIX_request_pop(void)
39 {
40   smx_req_t request = NULL;
41   xbt_os_mutex_acquire(sync_req_vector);
42   while(xbt_dynar_length(req_vector)){
43     request = xbt_dynar_pop_as(req_vector, smx_req_t);
44     if(request)
45       break;
46   }
47   xbt_os_mutex_release(sync_req_vector);
48   return request;
49 }
50
51 void SIMIX_request_answer(smx_req_t req)
52 {
53   if(req->issuer != simix_global->maestro_process){
54     req->issuer->request = NULL;    
55     xbt_swag_insert(req->issuer, simix_global->process_to_run);
56   }
57 }
58
59 int SIMIX_request_isVisible(smx_req_t req)
60 {
61   if(req->call != REQ_COMM_ISEND && req->call != REQ_COMM_IRECV
62    && req->call != REQ_COMM_WAIT && req->call != REQ_COMM_WAITANY
63    && req->call != REQ_COMM_TEST)
64     return FALSE;
65   return TRUE;
66 }
67
68 int SIMIX_request_isEnabled(smx_req_t req)
69 {
70   unsigned int index = 0;
71   smx_action_t act;
72   
73   switch(req->call){
74     case REQ_COMM_WAIT:
75       /*FIXME: check also that src and dst processes are not suspended */
76       if(req->comm_wait.comm->comm.src_proc 
77          && req->comm_wait.comm->comm.dst_proc)
78         return TRUE;
79       return FALSE;
80       break;
81       
82     case REQ_COMM_WAITANY:
83       xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
84         if (act->comm.src_proc && act->comm.dst_proc){
85           return TRUE;
86         }
87       }
88       return FALSE;
89       break;
90
91     default:    
92       return TRUE;
93   }
94 }
95
96
97 void SIMIX_request_pre(smx_req_t req)
98 {
99   switch (req->call) {
100
101     case REQ_HOST_GET_BY_NAME:
102       req->host_get_by_name.result =
103         SIMIX_host_get_by_name(req->host_get_by_name.name);
104       SIMIX_request_answer(req);
105       break;
106     case REQ_HOST_GET_NAME:
107       req->host_get_name.result =       SIMIX_host_get_name(req->host_get_name.host);
108       SIMIX_request_answer(req);
109       break;
110     case REQ_HOST_GET_PROPERTIES:
111       req->host_get_properties.result =
112         SIMIX_host_get_properties(req->host_get_properties.host);
113       SIMIX_request_answer(req);
114       break;
115     case REQ_HOST_GET_SPEED:
116       req->host_get_speed.result = 
117         SIMIX_host_get_speed(req->host_get_speed.host);
118       SIMIX_request_answer(req);
119       break;
120     case REQ_HOST_GET_AVAILABLE_SPEED:
121       req->host_get_available_speed.result =
122         SIMIX_host_get_available_speed(req->host_get_available_speed.host);
123       SIMIX_request_answer(req);
124       break;
125     case REQ_HOST_GET_STATE:
126       req->host_get_state.result = 
127         SIMIX_host_get_state(req->host_get_state.host);
128       SIMIX_request_answer(req);
129       break;
130     case REQ_HOST_GET_DATA:
131       req->host_get_data.result =       SIMIX_host_get_data(req->host_get_data.host);
132       SIMIX_request_answer(req);
133       break;
134     case REQ_HOST_SET_DATA:
135       SIMIX_host_set_data(req->host_set_data.host, req->host_set_data.data);
136       SIMIX_request_answer(req);
137       break;
138     case REQ_HOST_EXECUTE:
139       req->host_execute.result = SIMIX_host_execute(
140           req->host_execute.name,
141           req->host_execute.host,
142           req->host_execute.computation_amount);
143       SIMIX_request_answer(req);
144       break;
145     case REQ_HOST_PARALLEL_EXECUTE:
146       req->host_parallel_execute.result = SIMIX_host_parallel_execute(
147           req->host_parallel_execute.name,
148           req->host_parallel_execute.host_nb,
149           req->host_parallel_execute.host_list,
150           req->host_parallel_execute.computation_amount,
151           req->host_parallel_execute.communication_amount,
152           req->host_parallel_execute.amount,
153           req->host_parallel_execute.rate);
154       SIMIX_request_answer(req);
155       break;
156     case REQ_HOST_EXECUTION_DESTROY:
157       SIMIX_host_execution_destroy(req->host_execution_destroy.execution);
158       SIMIX_request_answer(req);
159       break;
160     case REQ_HOST_EXECUTION_CANCEL:
161       SIMIX_host_execution_cancel(req->host_execution_cancel.execution);
162       SIMIX_request_answer(req);
163       break;
164     case REQ_HOST_EXECUTION_GET_REMAINS:
165       req->host_execution_get_remains.result =
166         SIMIX_host_execution_get_remains(req->host_execution_get_remains.execution);
167       SIMIX_request_answer(req);
168       break;
169     case REQ_HOST_EXECUTION_GET_STATE:
170       req->host_execution_get_state.result =
171         SIMIX_host_execution_get_state(req->host_execution_get_state.execution);
172       SIMIX_request_answer(req);
173       break;
174     case REQ_HOST_EXECUTION_SET_PRIORITY:
175       SIMIX_host_execution_set_priority(
176           req->host_execution_set_priority.execution,
177           req->host_execution_set_priority.priority);
178       SIMIX_request_answer(req);
179       break;
180     case REQ_HOST_EXECUTION_WAIT:
181       SIMIX_pre_host_execution_wait(req);
182       break;
183     case REQ_PROCESS_CREATE:
184       req->process_create.result = SIMIX_process_create(
185           req->process_create.name,
186           req->process_create.code,
187           req->process_create.data,
188           req->process_create.hostname,
189           req->process_create.argc,
190           req->process_create.argv,
191           req->process_create.properties);
192       SIMIX_request_answer(req);
193       break;
194     case REQ_PROCESS_KILL:
195       SIMIX_process_kill(req->process_kill.process, req->issuer);
196       SIMIX_request_answer(req);
197       break;
198     case REQ_PROCESS_CHANGE_HOST:
199       SIMIX_process_change_host(
200           req->process_change_host.process,
201           req->process_change_host.source,
202           req->process_change_host.dest);
203       SIMIX_request_answer(req);
204       break;
205     case REQ_PROCESS_SUSPEND:
206       SIMIX_pre_process_suspend(req);
207       break;
208     case REQ_PROCESS_RESUME:
209       SIMIX_process_resume(req->process_resume.process, req->issuer);
210       SIMIX_request_answer(req);
211       break;
212     case REQ_PROCESS_COUNT:
213       req->process_count.result = SIMIX_process_count();
214       SIMIX_request_answer(req);
215       break;
216     case REQ_PROCESS_GET_DATA:
217       req->process_get_data.result =
218         SIMIX_process_get_data(req->process_get_data.process);
219       SIMIX_request_answer(req);
220       break;
221     case REQ_PROCESS_SET_DATA:
222       SIMIX_process_set_data(
223           req->process_set_data.process,
224           req->process_set_data.data);
225       SIMIX_request_answer(req);
226       break;
227     case REQ_PROCESS_GET_HOST:
228       req->process_get_host.result = SIMIX_process_get_host(req->process_get_host.process);
229       SIMIX_request_answer(req);
230       break;
231     case REQ_PROCESS_GET_NAME:
232       req->process_get_name.result = SIMIX_process_get_name(req->process_get_name.process);
233       SIMIX_request_answer(req);
234       break;
235     case REQ_PROCESS_IS_SUSPENDED:
236       req->process_is_suspended.result =
237         SIMIX_process_is_suspended(req->process_is_suspended.process);
238       SIMIX_request_answer(req);
239       break;
240     case REQ_PROCESS_GET_PROPERTIES:
241       req->process_get_properties.result =
242         SIMIX_process_get_properties(req->process_get_properties.process);
243       SIMIX_request_answer(req);
244       break;
245     case REQ_PROCESS_SLEEP:
246       SIMIX_pre_process_sleep(req);
247       break;
248     case REQ_RDV_CREATE:
249       req->rdv_create.result = SIMIX_rdv_create(req->rdv_create.name);
250       SIMIX_request_answer(req);
251       break;
252     case REQ_RDV_DESTROY:
253       SIMIX_rdv_destroy(req->rdv_destroy.rdv);
254       SIMIX_request_answer(req);
255       break;
256     case REQ_RDV_GEY_BY_NAME:
257       req->rdv_get_by_name.result = 
258         SIMIX_rdv_get_by_name(req->rdv_get_by_name.name);
259       SIMIX_request_answer(req);
260       break;
261     case REQ_RDV_COMM_COUNT_BY_HOST:
262       req->rdv_comm_count_by_host.result = SIMIX_rdv_comm_count_by_host(
263           req->rdv_comm_count_by_host.rdv,
264           req->rdv_comm_count_by_host.host);
265       SIMIX_request_answer(req);
266       break;
267     case REQ_RDV_GET_HEAD:
268       req->rdv_get_head.result =        SIMIX_rdv_get_head(req->rdv_get_head.rdv);
269       SIMIX_request_answer(req);
270       break;
271     case REQ_COMM_ISEND:
272       req->comm_isend.result = SIMIX_comm_isend(
273           req->issuer,
274           req->comm_isend.rdv,
275           req->comm_isend.task_size,
276           req->comm_isend.rate,
277           req->comm_isend.src_buff,
278           req->comm_isend.src_buff_size,
279           req->comm_isend.data);
280       SIMIX_request_answer(req);
281       break;
282     case REQ_COMM_IRECV:
283       req->comm_irecv.result = SIMIX_comm_irecv(
284           req->issuer,
285           req->comm_irecv.rdv,
286           req->comm_irecv.dst_buff,
287           req->comm_irecv.dst_buff_size);
288       SIMIX_request_answer(req);
289       break;
290     case REQ_COMM_DESTROY:
291       SIMIX_comm_destroy(req->comm_destroy.comm);
292       SIMIX_request_answer(req);
293       break;
294     case REQ_COMM_CANCEL:
295       SIMIX_comm_cancel(req->comm_cancel.comm);
296       SIMIX_request_answer(req);
297       break;
298     case REQ_COMM_WAITANY:
299       SIMIX_pre_comm_waitany(req);
300       break;
301     case REQ_COMM_WAIT:
302       SIMIX_pre_comm_wait(req);
303       break;
304     case REQ_COMM_TEST:
305       SIMIX_pre_comm_test(req);
306       break;
307     case REQ_COMM_GET_REMAINS:
308       req->comm_get_remains.result = 
309         SIMIX_comm_get_remains(req->comm_get_remains.comm);
310       SIMIX_request_answer(req);
311       break;
312     case REQ_COMM_GET_STATE:
313       req->comm_get_state.result = 
314         SIMIX_comm_get_state(req->comm_get_state.comm);
315       SIMIX_request_answer(req);
316       break;
317     case REQ_COMM_GET_DATA:
318       req->comm_get_data.result = SIMIX_comm_get_data(req->comm_get_data.comm);
319       SIMIX_request_answer(req);
320       break;
321     case REQ_COMM_GET_SRC_BUFF:
322       req->comm_get_src_buff.result =
323         SIMIX_comm_get_src_buff(req->comm_get_src_buff.comm);
324       SIMIX_request_answer(req);
325       break;
326     case REQ_COMM_GET_DST_BUFF:
327       req->comm_get_dst_buff.result =
328         SIMIX_comm_get_dst_buff(req->comm_get_dst_buff.comm);
329       SIMIX_request_answer(req);
330       break;
331     case REQ_COMM_GET_SRC_BUFF_SIZE:
332       req->comm_get_src_buff_size.result = 
333         SIMIX_comm_get_src_buff_size(req->comm_get_src_buff_size.comm);
334       SIMIX_request_answer(req);
335       break;
336     case REQ_COMM_GET_DST_BUFF_SIZE:
337       req->comm_get_dst_buff_size.result =
338         SIMIX_comm_get_dst_buff_size(req->comm_get_dst_buff_size.comm);
339       SIMIX_request_answer(req);
340       break;
341     case REQ_COMM_GET_SRC_PROC:
342       req->comm_get_src_proc.result = 
343         SIMIX_comm_get_src_proc(req->comm_get_src_proc.comm);
344       SIMIX_request_answer(req);
345       break;
346     case REQ_COMM_GET_DST_PROC:
347       req->comm_get_dst_proc.result =
348         SIMIX_comm_get_dst_proc(req->comm_get_dst_proc.comm);
349       SIMIX_request_answer(req);
350       break;
351 #ifdef HAVE_LATENCY_BOUND_TRACKING
352     case REQ_COMM_IS_LATENCY_BOUNDED:
353       req->comm_is_latency_bounded.result =
354         SIMIX_comm_is_latency_bounded(req->comm_is_latency_bounded.comm);
355       SIMIX_request_answer(req);
356       break;
357 #endif
358     case REQ_MUTEX_INIT:
359       req->mutex_init.result = SIMIX_mutex_init();
360       SIMIX_request_answer(req);
361       break;
362     case REQ_MUTEX_DESTROY:
363       SIMIX_mutex_destroy(req->mutex_destroy.mutex);
364       SIMIX_request_answer(req);
365       break;
366     case REQ_MUTEX_LOCK:
367       SIMIX_pre_mutex_lock(req);
368       break;
369     case REQ_MUTEX_TRYLOCK:
370       req->mutex_trylock.result =
371               SIMIX_mutex_trylock(req->mutex_trylock.mutex, req->issuer);
372       SIMIX_request_answer(req);
373       break;
374     case REQ_MUTEX_UNLOCK:
375       SIMIX_mutex_unlock(req->mutex_unlock.mutex, req->issuer);
376       SIMIX_request_answer(req);
377       break;
378     case REQ_COND_INIT:
379       req->cond_init.result = SIMIX_cond_init();
380       SIMIX_request_answer(req);
381       break;
382     case REQ_COND_DESTROY:
383       SIMIX_cond_destroy(req->cond_destroy.cond);
384       SIMIX_request_answer(req);
385       break;
386     case REQ_COND_SIGNAL:
387       SIMIX_cond_signal(req->cond_signal.cond);
388       SIMIX_request_answer(req);
389       break;
390     case REQ_COND_WAIT:
391       SIMIX_pre_cond_wait(req);
392       break;
393     case REQ_COND_WAIT_TIMEOUT:
394       SIMIX_pre_cond_wait_timeout(req);
395       break;
396     case REQ_COND_BROADCAST:
397       SIMIX_cond_broadcast(req->cond_broadcast.cond);
398       SIMIX_request_answer(req);
399       break;
400     case REQ_SEM_INIT:
401       req->sem_init.result = SIMIX_sem_init(req->sem_init.capacity);
402       SIMIX_request_answer(req);
403       break;
404     case REQ_SEM_DESTROY:
405       SIMIX_sem_destroy(req->sem_destroy.sem);
406       SIMIX_request_answer(req);
407       break;
408     case REQ_SEM_RELEASE:
409       SIMIX_sem_release(req->sem_release.sem);
410       SIMIX_request_answer(req);
411       break;
412     case REQ_SEM_WOULD_BLOCK:
413       req->sem_would_block.result =
414         SIMIX_sem_would_block(req->sem_would_block.sem);
415       SIMIX_request_answer(req);
416       break;
417     case REQ_SEM_ACQUIRE:
418       SIMIX_pre_sem_acquire(req);
419       break;
420     case REQ_SEM_ACQUIRE_TIMEOUT:
421       SIMIX_pre_sem_acquire_timeout(req);
422       break;
423     case REQ_SEM_GET_CAPACITY:
424       req->sem_get_capacity.result = 
425         SIMIX_sem_get_capacity(req->sem_get_capacity.sem);
426       SIMIX_request_answer(req);
427       break;
428   }
429 }
430
431 void SIMIX_request_post(smx_action_t action)
432 {
433   switch(action->type) {
434     case SIMIX_ACTION_EXECUTE:
435     case SIMIX_ACTION_PARALLEL_EXECUTE:
436       SIMIX_post_host_execute(action);
437       break;
438     case SIMIX_ACTION_COMMUNICATE:
439       SIMIX_post_comm(action);
440       break;
441     case SIMIX_ACTION_SLEEP:
442       SIMIX_post_process_sleep(action);
443       break;
444     case SIMIX_ACTION_SYNCHRO:
445       SIMIX_post_synchro(action);
446       break;
447     case SIMIX_ACTION_IO:
448       break;
449   }
450 }