Logo AND Algorithmique Numérique Distribuée

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