Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Set level COORD_HOST_LEVEL and COORD_ASR_LEVEL if there are used.
[simgrid.git] / src / simix / smx_user.c
1 #include "private.h"
2 #include "mc/mc.h"
3
4 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
5
6 static const char* request_names[] = {
7 #undef SIMIX_REQ_ENUM_ELEMENT
8 #define SIMIX_REQ_ENUM_ELEMENT(x) #x /* generate strings from the enumeration values */
9 SIMIX_REQ_LIST
10 #undef SIMIX_REQ_ENUM_ELEMENT
11 };
12
13 /**
14  * \brief Returns a host given its name.
15  *
16  * \param name The name of the host to get
17  * \return The corresponding host
18  */
19 smx_host_t SIMIX_req_host_get_by_name(const char *name)
20 {
21   smx_req_t req = SIMIX_req_mine();
22
23   req->call = REQ_HOST_GET_BY_NAME;
24   req->host_get_by_name.name = name;
25   SIMIX_request_push();
26   return req->host_get_by_name.result;
27 }
28
29 /**
30  * \brief Returns the name of a host.
31  *
32  * \param host A SIMIX host
33  * \return The name of this host
34  */
35 const char* SIMIX_req_host_get_name(smx_host_t host)
36 {
37   smx_req_t req = SIMIX_req_mine();
38
39   req->call = REQ_HOST_GET_NAME;
40   req->host_get_name.host = host;
41   SIMIX_request_push();
42   return req->host_get_name.result;
43 }
44
45 /**
46  * \brief Returns a dict of the properties assigned to a host.
47  *
48  * \param host A host
49  * \return The properties of this host
50  */
51 xbt_dict_t SIMIX_req_host_get_properties(smx_host_t host)
52 {
53   smx_req_t req = SIMIX_req_mine();
54
55   req->call = REQ_HOST_GET_PROPERTIES;
56   req->host_get_properties.host = host;
57   SIMIX_request_push();
58   return req->host_get_properties.result;
59 }
60
61 /**
62  * \brief Returns the speed of the processor.
63  *
64  * The speed returned does not take into account the current load on the machine.
65  * \param host A SIMIX host
66  * \return The speed of this host (in Mflop/s)
67  */
68 double SIMIX_req_host_get_speed(smx_host_t host)
69 {
70   smx_req_t req = SIMIX_req_mine();
71
72   req->call = REQ_HOST_GET_SPEED;
73   req->host_get_speed.host = host;
74   SIMIX_request_push();
75   return req->host_get_speed.result;
76 }
77
78 /**
79  * \brief Returns the available speed of the processor.
80  *
81  * \return Speed currently available (in Mflop/s)
82  */
83 double SIMIX_req_host_get_available_speed(smx_host_t host)
84 {
85   smx_req_t req = SIMIX_req_mine();
86
87   req->call = REQ_HOST_GET_AVAILABLE_SPEED;
88   req->host_get_available_speed.host = host;
89   SIMIX_request_push();
90   return req->host_get_available_speed.result;
91 }
92
93 /**
94  * \brief Returns the state of a host.
95  *
96  * Two states are possible: 1 if the host is active or 0 if it has crashed.
97  * \param host A SIMIX host
98  * \return 1 if the host is available, 0 otherwise
99  */
100 int SIMIX_req_host_get_state(smx_host_t host)
101 {
102   smx_req_t req = SIMIX_req_mine();
103
104   req->call = REQ_HOST_GET_STATE;
105   req->host_get_state.host = host;
106   SIMIX_request_push();
107   return req->host_get_state.result;
108 }
109
110 /**
111  * \brief Returns the user data associated to a host.
112  *
113  * \param host SIMIX host
114  * \return the user data of this host
115  */
116 void* SIMIX_req_host_get_data(smx_host_t host)
117 {
118   smx_req_t req = SIMIX_req_mine();
119
120   req->call = REQ_HOST_GET_DATA;
121   req->host_get_data.host = host;
122   SIMIX_request_push();
123   return req->host_get_data.result;
124 }
125
126 /**
127  * \brief Sets the user data associated to a host.
128  *
129  * The host must not have previous user data associated to it.
130  * \param A host SIMIX host
131  * \param data The user data to set
132  */
133 void SIMIX_req_host_set_data(smx_host_t host, void *data)
134 {
135   smx_req_t req = SIMIX_req_mine();
136
137   req->call = REQ_HOST_SET_DATA;
138   req->host_set_data.host = host;
139   req->host_set_data.data = data;
140   SIMIX_request_push();
141 }
142
143 /** \brief Creates an action that executes some computation of an host.
144  *
145  * This function creates a SURF action and allocates the data necessary
146  * to create the SIMIX action. It can raise a host_error exception if the host crashed.
147  *
148  * \param name Name of the execution action to create
149  * \param host SIMIX host where the action will be executed
150  * \param amount Computation amount (in bytes)
151  * \return A new SIMIX execution action
152  */
153 smx_action_t SIMIX_req_host_execute(const char *name, smx_host_t host,
154                                     double computation_amount,
155                                     double priority)
156 {
157   smx_req_t req = SIMIX_req_mine();
158
159   req->call = REQ_HOST_EXECUTE;
160   req->host_execute.name = name;
161   req->host_execute.host = host;
162   req->host_execute.computation_amount = computation_amount;
163   req->host_execute.priority = priority;
164   SIMIX_request_push();
165   return req->host_execute.result;
166 }
167
168 /** \brief Creates an action that may involve parallel computation on
169  * several hosts and communication between them.
170  *
171  * \param name Name of the execution action to create
172  * \param host_nb Number of hosts where the action will be executed
173  * \param host_list Array (of size host_nb) of hosts where the action will be executed
174  * \param computation_amount Array (of size host_nb) of computation amount of hosts (in bytes)
175  * \param communication_amount Array (of size host_nb * host_nb) representing the communication
176  * amount between each pair of hosts
177  * \param amount the SURF action amount
178  * \param rate the SURF action rate
179  * \return A new SIMIX execution action
180  */
181 smx_action_t SIMIX_req_host_parallel_execute(const char *name,
182                                          int host_nb,
183                                          smx_host_t *host_list,
184                                          double *computation_amount,
185                                          double *communication_amount,
186                                          double amount,
187                                          double rate)
188 {
189   smx_req_t req = SIMIX_req_mine();
190
191   req->call = REQ_HOST_PARALLEL_EXECUTE;
192   req->host_parallel_execute.name = name;
193   req->host_parallel_execute.host_nb = host_nb;
194   req->host_parallel_execute.host_list = host_list;
195   req->host_parallel_execute.computation_amount = computation_amount;
196   req->host_parallel_execute.communication_amount = communication_amount;
197   req->host_parallel_execute.amount = amount;
198   req->host_parallel_execute.rate = rate;
199   SIMIX_request_push();
200   return req->host_parallel_execute.result;
201 }
202
203 /**
204  * \brief Destroys an execution action.
205  *
206  * Destroys an action, freing its memory. This function cannot be called if there are a conditional waiting for it.
207  * \param action The execution action to destroy
208  */
209 void SIMIX_req_host_execution_destroy(smx_action_t execution)
210 {
211   smx_req_t req = SIMIX_req_mine();
212
213   req->call = REQ_HOST_EXECUTION_DESTROY;
214   req->host_execution_destroy.execution = execution;
215   SIMIX_request_push();
216 }
217
218 /**
219  * \brief Cancels an execution action.
220  *
221  * This functions stops the execution. It calls a surf function.
222  * \param action The execution action to cancel
223  */
224 void SIMIX_req_host_execution_cancel(smx_action_t execution)
225 {
226   smx_req_t req = SIMIX_req_mine();
227
228   req->call = REQ_HOST_EXECUTION_CANCEL;
229   req->host_execution_cancel.execution = execution;
230   SIMIX_request_push();
231 }
232
233 /**
234  * \brief Returns how much of an execution action remains to be done.
235  *
236  * \param Action The execution action
237  * \return The remaining amount
238  */
239 double SIMIX_req_host_execution_get_remains(smx_action_t execution)
240 {
241   smx_req_t req = SIMIX_req_mine();
242
243   req->call = REQ_HOST_EXECUTION_GET_REMAINS;
244   req->host_execution_get_remains.execution = execution;
245   SIMIX_request_push();
246   return req->host_execution_get_remains.result;
247 }
248
249 /**
250  * \brief Returns the state of an execution action.
251  *
252  * \param execution The execution action
253  * \return The state
254  */
255 e_smx_state_t SIMIX_req_host_execution_get_state(smx_action_t execution)
256 {
257   smx_req_t req = SIMIX_req_mine();
258
259   req->call = REQ_HOST_EXECUTION_GET_STATE;
260   req->host_execution_get_state.execution = execution;
261   SIMIX_request_push();
262   return req->host_execution_get_state.result;
263 }
264
265 /**
266  * \brief Changes the priority of an execution action.
267  *
268  * This functions changes the priority only. It calls a surf function.
269  * \param execution The execution action
270  * \param priority The new priority
271  */
272 void SIMIX_req_host_execution_set_priority(smx_action_t execution, double priority)
273 {
274   smx_req_t req = SIMIX_req_mine();
275
276   req->call = REQ_HOST_EXECUTION_SET_PRIORITY;
277   req->host_execution_set_priority.execution = execution;
278   req->host_execution_set_priority.priority = priority;
279   SIMIX_request_push();
280 }
281
282 /**
283  * \brief Waits for the completion of an execution action and destroy it.
284  *
285  * \param execution The execution action
286  */
287 e_smx_state_t SIMIX_req_host_execution_wait(smx_action_t execution)
288 {
289   smx_req_t req = SIMIX_req_mine();
290
291   req->call = REQ_HOST_EXECUTION_WAIT;
292   req->host_execution_wait.execution = execution;
293   SIMIX_request_push();
294   return req->host_execution_wait.result;
295 }
296
297 /**
298  * \brief Creates and runs a new SIMIX process.
299  *
300  * The structure and the corresponding thread are created and put in the list of ready processes.
301  *
302  * \param process the process created will be stored in this pointer
303  * \param name a name for the process. It is for user-level information and can be NULL.
304  * \param code the main function of the process
305  * \param data a pointer to any data one may want to attach to the new object. It is for user-level information and can be NULL.
306  * It can be retrieved with the function \ref SIMIX_req_process_get_data.
307  * \param hostname name of the host where the new agent is executed.
308  * \param argc first argument passed to \a code
309  * \param argv second argument passed to \a code
310  * \param properties the properties of the process
311  */
312 void SIMIX_req_process_create(smx_process_t *process, const char *name,
313                               xbt_main_func_t code,
314                               void *data,
315                               const char *hostname,
316                               int argc, char **argv,
317                               xbt_dict_t properties)
318 {
319   smx_req_t req = SIMIX_req_mine();
320
321   req->call = REQ_PROCESS_CREATE;
322   req->process_create.process = process;
323   req->process_create.name = name;
324   req->process_create.code = code;
325   req->process_create.data = data;
326   req->process_create.hostname = hostname;
327   req->process_create.argc = argc;
328   req->process_create.argv = argv;
329   req->process_create.properties = properties;
330   SIMIX_request_push();
331 }
332
333 /** \brief Kills a SIMIX process.
334  *
335  * This function simply kills a  process.
336  *
337  * \param process poor victim
338  */
339 void SIMIX_req_process_kill(smx_process_t process)
340 {
341   smx_req_t req = SIMIX_req_mine();
342
343   req->call = REQ_PROCESS_KILL;
344   req->process_kill.process = process;
345   SIMIX_request_push();
346 }
347
348 /** \brief Kills all SIMIX processes.
349  */
350 void SIMIX_req_process_killall(void)
351 {
352   smx_req_t req = SIMIX_req_mine();
353
354   req->call = REQ_PROCESS_KILLALL;
355   SIMIX_request_push();
356 }
357
358 /** \brief Cleans up a SIMIX process.
359  * \param process poor victim (must have already been killed)
360  */
361 void SIMIX_req_process_cleanup(smx_process_t process)
362 {
363   smx_req_t req = SIMIX_req_mine();
364
365   req->call = REQ_PROCESS_CLEANUP;
366   req->process_cleanup.process = process;
367   SIMIX_request_push();
368 }
369
370 /**
371  * \brief Migrates an agent to another location.
372  *
373  * This function changes the value of the host on which \a process is running.
374  *
375  * \param process the process to migrate
376  * \param source name of the previous host
377  * \param dest name of the new host
378  */
379 void SIMIX_req_process_change_host(smx_process_t process, const char *source, const char *dest)
380 {
381   smx_req_t req = SIMIX_req_mine();
382
383   req->call = REQ_PROCESS_CHANGE_HOST;
384   req->process_change_host.process = process;
385   req->process_change_host.source = source;
386   req->process_change_host.dest = dest;
387   SIMIX_request_push();
388 }
389
390 /**
391  * \brief Suspends a process.
392  *
393  * This function suspends the process by suspending the action
394  * it was waiting for completion.
395  *
396  * \param process a SIMIX process
397  */
398 void SIMIX_req_process_suspend(smx_process_t process)
399 {
400   xbt_assert0(process, "Invalid parameters");
401
402   smx_req_t req = SIMIX_req_mine();
403
404   req->call = REQ_PROCESS_SUSPEND;
405   req->process_suspend.process = process;
406   SIMIX_request_push();
407 }
408
409 /**
410  * \brief Resumes a suspended process.
411  *
412  * This function resumes a suspended process by resuming the action
413  * it was waiting for completion.
414  *
415  * \param process a SIMIX process
416  */
417 void SIMIX_req_process_resume(smx_process_t process)
418 {
419   smx_req_t req = SIMIX_req_mine();
420
421   req->call = REQ_PROCESS_RESUME;
422   req->process_resume.process = process;
423   SIMIX_request_push();
424 }
425
426 /**
427  * \brief Returns the amount of SIMIX processes in the system
428  *
429  * Maestro internal process is not counted, only user code processes are
430  */
431 int SIMIX_req_process_count(void)
432 {
433   smx_req_t req = SIMIX_req_mine();
434
435   req->call = REQ_PROCESS_COUNT;
436   SIMIX_request_push();
437   return req->process_count.result;
438 }
439
440 /**
441  * \brief Return the user data of a #smx_process_t.
442  *
443  * This functions checks whether \a process is a valid pointer or not and return the user data associated to \a process if it is possible.
444  * \param process SIMIX process
445  * \return A void pointer to the user data
446  */
447 void* SIMIX_req_process_get_data(smx_process_t process)
448 {
449   if (process == SIMIX_process_self()) {
450     /* avoid a request if this function is called by the process itself */
451     return SIMIX_process_self_get_data();
452   }
453
454   smx_req_t req = SIMIX_req_mine();
455
456   req->call = REQ_PROCESS_GET_DATA;
457   req->process_get_data.process = process;
458   SIMIX_request_push();
459   return req->process_get_data.result;
460 }
461
462 /**
463  * \brief Set the user data of a #m_process_t.
464  *
465  * This functions checks whether \a process is a valid pointer or not and set the user data associated to \a process if it is possible.
466  * \param process SIMIX process
467  * \param data User data
468  */
469 void SIMIX_req_process_set_data(smx_process_t process, void *data)
470 {
471   if (process == SIMIX_process_self()) {
472     /* avoid a request if this function is called by the process itself */
473     SIMIX_process_self_set_data(data);
474   }
475   else {
476
477     smx_req_t req = SIMIX_req_mine();
478
479     req->call = REQ_PROCESS_SET_DATA;
480     req->process_set_data.process = process;
481     req->process_set_data.data = data;
482     SIMIX_request_push();
483   }
484 }
485
486 /**
487  * \brief Return the location on which an agent is running.
488  *
489  * This functions checks whether \a process is a valid pointer or not and return the m_host_t corresponding to the location on which \a process is running.
490  * \param process SIMIX process
491  * \return SIMIX host
492  */
493 smx_host_t SIMIX_req_process_get_host(smx_process_t process)
494 {
495   smx_req_t req = SIMIX_req_mine();
496
497   req->call = REQ_PROCESS_GET_HOST;
498   req->process_get_host.process = process;
499   SIMIX_request_push();
500   return req->process_get_host.result;
501 }
502
503 /**
504  * \brief Return the name of an agent.
505  *
506  * This functions checks whether \a process is a valid pointer or not and return its name.
507  * \param process SIMIX process
508  * \return The process name
509  */
510 const char* SIMIX_req_process_get_name(smx_process_t process)
511 {
512   if (process == SIMIX_process_self()) {
513     /* avoid a request if this function is called by the process itself */
514     return process->name;
515   }
516
517   smx_req_t req = SIMIX_req_mine();
518
519   req->call = REQ_PROCESS_GET_NAME;
520   req->process_get_name.process = process;
521   SIMIX_request_push();
522   return req->process_get_name.result;
523 }
524
525 /**
526  * \brief Returns true if the process is suspended .
527  *
528  * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
529  * \param process SIMIX process
530  * \return 1, if the process is suspended, else 0.
531  */
532 int SIMIX_req_process_is_suspended(smx_process_t process)
533 {
534   smx_req_t req = SIMIX_req_mine();
535
536   req->call = REQ_PROCESS_IS_SUSPENDED;
537   req->process_is_suspended.process = process;
538   SIMIX_request_push();
539   return req->process_is_suspended.result;
540 }
541
542 /** \ingroup m_process_management
543  * \brief Return the properties
544  *
545  * This functions returns the properties associated with this process
546  */
547 xbt_dict_t SIMIX_req_process_get_properties(smx_process_t process)
548 {
549   smx_req_t req = SIMIX_req_mine();
550
551   req->call = REQ_PROCESS_GET_PROPERTIES;
552   req->process_get_properties.process = process;
553   SIMIX_request_push();
554   return req->process_get_properties.result;
555 }
556
557 /** \brief Creates a new sleep SIMIX action.
558  *
559  * This function creates a SURF action and allocates the data necessary
560  * to create the SIMIX action. It can raise a host_error exception if the
561  * host crashed. The default SIMIX name of the action is "sleep".
562  *
563  *      \param duration Time duration of the sleep.
564  *      \return A result telling whether the sleep was successful
565  */
566 e_smx_state_t SIMIX_req_process_sleep(double duration)
567 {
568   smx_req_t req = SIMIX_req_mine();
569
570   req->call = REQ_PROCESS_SLEEP;
571   req->process_sleep.duration = duration;
572   SIMIX_request_push();
573   return req->process_sleep.result;
574 }
575
576 /**
577  *  \brief Creates a new rendez-vous point
578  *  \param name The name of the rendez-vous point
579  *  \return The created rendez-vous point
580  */
581 smx_rdv_t SIMIX_req_rdv_create(const char *name)
582 {
583   smx_req_t req = SIMIX_req_mine();
584
585   req->call = REQ_RDV_CREATE;
586   req->rdv_create.name = name;
587
588   SIMIX_request_push();
589   return req->rdv_create.result;
590 }
591
592
593 /**
594  *  \brief Destroy a rendez-vous point
595  *  \param name The rendez-vous point to destroy
596  */
597 void SIMIX_req_rdv_destroy(smx_rdv_t rdv)
598 {
599   smx_req_t req = SIMIX_req_mine();
600
601   req->call = REQ_RDV_DESTROY;
602   req->rdv_destroy.rdv = rdv;
603
604   SIMIX_request_push();
605 }
606
607 smx_rdv_t SIMIX_req_rdv_get_by_name(const char *name)
608 {
609   xbt_assert0(name != NULL, "Invalid parameter for SIMIX_req_rdv_get_by_name (name is NULL)");
610
611   /* FIXME: this is a horrible lost of performance, so we hack it out by
612    * skipping the request (for now). It won't work on distributed but
613    * probably we will change MSG for that. */
614 /*
615   smx_req_t req = SIMIX_req_mine();
616   req->call = REQ_RDV_GEY_BY_NAME;
617   req->rdv_get_by_name.name = name;
618   SIMIX_request_push();
619   return req->rdv_get_by_name.result;*/
620
621   return SIMIX_rdv_get_by_name(name);
622 }
623
624 /**
625  *  \brief counts the number of communication requests of a given host pending
626  *         on a rendez-vous point
627  *  \param rdv The rendez-vous point
628  *  \param host The host to be counted
629  *  \return The number of comm request pending in the rdv
630  */
631 int SIMIX_req_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
632 {
633   smx_req_t req = SIMIX_req_mine();
634
635   req->call = REQ_RDV_COMM_COUNT_BY_HOST;
636   req->rdv_comm_count_by_host.rdv = rdv;
637   req->rdv_comm_count_by_host.host = host;
638
639   SIMIX_request_push();
640   return req->rdv_comm_count_by_host.result;
641 }
642
643 /**
644  *  \brief returns the communication at the head of the rendez-vous
645  *  \param rdv The rendez-vous point
646  *  \return The communication or NULL if empty
647  */
648 smx_action_t SIMIX_req_rdv_get_head(smx_rdv_t rdv)
649 {
650   smx_req_t req = SIMIX_req_mine();
651
652   req->call = REQ_RDV_GET_HEAD;
653   req->rdv_get_head.rdv = rdv;
654
655   SIMIX_request_push();
656   return req->rdv_get_head.result;
657 }
658
659 void SIMIX_req_comm_send(smx_rdv_t rdv, double task_size, double rate,
660                          void *src_buff, size_t src_buff_size,
661                          int (*match_fun)(void *, void *), void *data,
662                          double timeout)
663 {
664   xbt_assert0(rdv, "No rendez-vous point defined for send");
665
666   if (MC_IS_ENABLED) {
667     /* the model-checker wants two separate requests */
668     smx_action_t comm = SIMIX_req_comm_isend(rdv, task_size, rate,
669         src_buff, src_buff_size, match_fun, data, 0);
670     SIMIX_req_comm_wait(comm, timeout);
671   }
672   else {
673     smx_req_t req = SIMIX_req_mine();
674
675     req->call = REQ_COMM_SEND;
676     req->comm_send.rdv = rdv;
677     req->comm_send.task_size = task_size;
678     req->comm_send.rate = rate;
679     req->comm_send.src_buff = src_buff;
680     req->comm_send.src_buff_size = src_buff_size;
681     req->comm_send.match_fun = match_fun;
682     req->comm_send.data = data;
683     req->comm_send.timeout = timeout;
684
685     SIMIX_request_push();
686   }
687 }
688
689 smx_action_t SIMIX_req_comm_isend(smx_rdv_t rdv, double task_size, double rate,
690                               void *src_buff, size_t src_buff_size,
691                               int (*match_fun)(void *, void *), void *data,
692                               int detached)
693 {
694   xbt_assert0(rdv, "No rendez-vous point defined for isend");
695
696   smx_req_t req = SIMIX_req_mine();
697
698   req->call = REQ_COMM_ISEND;
699   req->comm_isend.rdv = rdv;
700   req->comm_isend.task_size = task_size;
701   req->comm_isend.rate = rate;
702   req->comm_isend.src_buff = src_buff;
703   req->comm_isend.src_buff_size = src_buff_size;
704   req->comm_isend.match_fun = match_fun;
705   req->comm_isend.data = data;
706   req->comm_isend.detached = detached;
707
708   SIMIX_request_push();
709   return req->comm_isend.result;
710 }
711
712 void SIMIX_req_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
713                          int (*match_fun)(void *, void *), void *data, double timeout)
714 {
715   xbt_assert0(rdv, "No rendez-vous point defined for recv");
716
717   if (MC_IS_ENABLED) {
718     /* the model-checker wants two separate requests */
719     smx_action_t comm = SIMIX_req_comm_irecv(rdv, dst_buff, dst_buff_size,
720         match_fun, data);
721     SIMIX_req_comm_wait(comm, timeout);
722   }
723   else {
724     smx_req_t req = SIMIX_req_mine();
725
726     req->call = REQ_COMM_RECV;
727     req->comm_recv.rdv = rdv;
728     req->comm_recv.dst_buff = dst_buff;
729     req->comm_recv.dst_buff_size = dst_buff_size;
730     req->comm_recv.match_fun = match_fun;
731     req->comm_recv.data = data;
732     req->comm_recv.timeout = timeout;
733
734     SIMIX_request_push();
735   }
736 }
737
738 smx_action_t SIMIX_req_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
739                                   int (*match_fun)(void *, void *), void *data)
740 {
741   xbt_assert0(rdv, "No rendez-vous point defined for irecv");
742
743   smx_req_t req = SIMIX_req_mine();
744
745   req->call = REQ_COMM_IRECV;
746   req->comm_irecv.rdv = rdv;
747   req->comm_irecv.dst_buff = dst_buff;
748   req->comm_irecv.dst_buff_size = dst_buff_size;
749   req->comm_irecv.match_fun = match_fun;
750   req->comm_irecv.data = data;
751
752   SIMIX_request_push();
753   return req->comm_irecv.result;
754 }
755
756 void SIMIX_req_comm_destroy(smx_action_t comm)
757 {
758   xbt_assert0(comm, "Invalid parameter");
759
760   /* FIXME remove this request type: comms are auto-destroyed now,
761    * but what happens with unfinished comms? */
762
763   /*
764   smx_req_t req = SIMIX_req_mine();
765
766   req->call = REQ_COMM_DESTROY;
767   req->comm_destroy.comm = comm;
768
769   SIMIX_request_push();
770   */
771 }
772
773 void SIMIX_req_comm_cancel(smx_action_t comm)
774 {
775   smx_req_t req = SIMIX_req_mine();
776
777   req->call = REQ_COMM_CANCEL;
778   req->comm_cancel.comm = comm;
779
780   SIMIX_request_push();
781 }
782
783 unsigned int SIMIX_req_comm_waitany(xbt_dynar_t comms)
784 {
785   smx_req_t req = SIMIX_req_mine();
786
787   req->call = REQ_COMM_WAITANY;
788   req->comm_waitany.comms = comms;
789
790   SIMIX_request_push();
791   return req->comm_waitany.result;
792 }
793
794 int SIMIX_req_comm_testany(xbt_dynar_t comms)
795 {
796   smx_req_t req = SIMIX_req_mine();
797   if (xbt_dynar_length(comms)==0)
798     return -1;
799
800   req->call = REQ_COMM_TESTANY;
801   req->comm_testany.comms = comms;
802
803   SIMIX_request_push();
804   return req->comm_testany.result;
805 }
806
807 void SIMIX_req_comm_wait(smx_action_t comm, double timeout)
808 {
809   smx_req_t req = SIMIX_req_mine();
810
811   req->call = REQ_COMM_WAIT;
812   req->comm_wait.comm = comm;
813   req->comm_wait.timeout = timeout;
814
815   SIMIX_request_push();
816 }
817
818 #ifdef HAVE_TRACING
819 /**
820  * \brief Set the category of an action.
821  *
822  * This functions changes the category only. It calls a surf function.
823  * \param execution The execution action
824  * \param category The tracing category
825  */
826 void SIMIX_req_set_category(smx_action_t action, const char *category)
827 {
828   if (category == NULL) {
829     return;
830   }
831
832   smx_req_t req = SIMIX_req_mine();
833
834   req->call = REQ_SET_CATEGORY;
835   req->set_category.action = action;
836   req->set_category.category = category;
837
838   SIMIX_request_push();
839 }
840 #endif
841
842 int SIMIX_req_comm_test(smx_action_t comm)
843 {
844   smx_req_t req = SIMIX_req_mine();
845
846   req->call = REQ_COMM_TEST;
847   req->comm_test.comm = comm;
848
849   SIMIX_request_push();
850   return req->comm_test.result;
851 }
852
853 double SIMIX_req_comm_get_remains(smx_action_t comm)
854 {
855   smx_req_t req = SIMIX_req_mine();
856
857   req->call = REQ_COMM_GET_REMAINS;
858   req->comm_get_remains.comm = comm;
859
860   SIMIX_request_push();
861   return req->comm_get_remains.result;
862 }
863
864 e_smx_state_t SIMIX_req_comm_get_state(smx_action_t comm)
865 {
866   smx_req_t req = SIMIX_req_mine();
867
868   req->call = REQ_COMM_GET_STATE;
869   req->comm_get_state.comm = comm;
870
871   SIMIX_request_push();
872   return req->comm_get_state.result;
873 }
874
875 void *SIMIX_req_comm_get_src_data(smx_action_t comm)
876 {
877   smx_req_t req = SIMIX_req_mine();
878
879   req->call = REQ_COMM_GET_SRC_DATA;
880   req->comm_get_src_data.comm = comm;
881
882   SIMIX_request_push();
883   return req->comm_get_src_data.result;
884 }
885
886 void *SIMIX_req_comm_get_dst_data(smx_action_t comm)
887 {
888   smx_req_t req = SIMIX_req_mine();
889
890   req->call = REQ_COMM_GET_DST_DATA;
891   req->comm_get_dst_data.comm = comm;
892
893   SIMIX_request_push();
894   return req->comm_get_dst_data.result;
895 }
896
897 smx_process_t SIMIX_req_comm_get_src_proc(smx_action_t comm)
898 {
899   smx_req_t req = SIMIX_req_mine();
900
901   req->call = REQ_COMM_GET_SRC_PROC;
902   req->comm_get_src_proc.comm = comm;
903
904   SIMIX_request_push();
905   return req->comm_get_src_proc.result;
906 }
907
908 smx_process_t SIMIX_req_comm_get_dst_proc(smx_action_t comm)
909 {
910   smx_req_t req = SIMIX_req_mine();
911
912   req->call = REQ_COMM_GET_DST_PROC;
913   req->comm_get_dst_proc.comm = comm;
914
915   SIMIX_request_push();
916   return req->comm_get_dst_proc.result;
917 }
918
919 #ifdef HAVE_LATENCY_BOUND_TRACKING
920 int SIMIX_req_comm_is_latency_bounded(smx_action_t comm)
921 {
922   smx_req_t req = SIMIX_req_mine();
923
924   req->call = REQ_COMM_IS_LATENCY_BOUNDED;
925   req->comm_is_latency_bounded.comm = comm;
926
927   SIMIX_request_push();
928   return req->comm_is_latency_bounded.result;
929 }
930 #endif
931
932 smx_mutex_t SIMIX_req_mutex_init(void)
933 {
934   smx_req_t req = SIMIX_req_mine();
935
936   req->call = REQ_MUTEX_INIT;
937
938   SIMIX_request_push();
939   return req->mutex_init.result;
940 }
941
942 void SIMIX_req_mutex_destroy(smx_mutex_t mutex)
943 {
944   smx_req_t req = SIMIX_req_mine();
945
946   req->call = REQ_MUTEX_DESTROY;
947   req->mutex_destroy.mutex = mutex;
948
949   SIMIX_request_push();
950 }
951
952 void SIMIX_req_mutex_lock(smx_mutex_t mutex)
953 {
954   smx_req_t req = SIMIX_req_mine();
955
956   req->call = REQ_MUTEX_LOCK;
957   req->mutex_lock.mutex = mutex;
958
959   SIMIX_request_push();
960 }
961
962 int SIMIX_req_mutex_trylock(smx_mutex_t mutex)
963 {
964   smx_req_t req = SIMIX_req_mine();
965
966   req->call = REQ_MUTEX_TRYLOCK;
967   req->mutex_trylock.mutex = mutex;
968
969   SIMIX_request_push();
970   return req->mutex_trylock.result;
971 }
972
973 void SIMIX_req_mutex_unlock(smx_mutex_t mutex)
974 {
975   smx_req_t req = SIMIX_req_mine();
976
977   req->call = REQ_MUTEX_UNLOCK;
978   req->mutex_unlock.mutex = mutex;
979
980   SIMIX_request_push();
981 }
982
983
984 smx_cond_t SIMIX_req_cond_init(void)
985 {
986   smx_req_t req = SIMIX_req_mine();
987
988   req->call = REQ_COND_INIT;
989
990   SIMIX_request_push();
991   return req->cond_init.result;
992 }
993
994 void SIMIX_req_cond_destroy(smx_cond_t cond)
995 {
996   smx_req_t req = SIMIX_req_mine();
997
998   req->call = REQ_COND_DESTROY;
999   req->cond_destroy.cond = cond;
1000
1001   SIMIX_request_push();
1002 }
1003
1004 void SIMIX_req_cond_signal(smx_cond_t cond)
1005 {
1006   smx_req_t req = SIMIX_req_mine();
1007
1008   req->call = REQ_COND_SIGNAL;
1009   req->cond_signal.cond = cond;
1010
1011   SIMIX_request_push();
1012 }
1013
1014 void SIMIX_req_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
1015 {
1016   smx_req_t req = SIMIX_req_mine();
1017
1018   req->call = REQ_COND_WAIT;
1019   req->cond_wait.cond = cond;
1020   req->cond_wait.mutex = mutex;
1021
1022   SIMIX_request_push();
1023 }
1024
1025 void SIMIX_req_cond_wait_timeout(smx_cond_t cond,
1026                                  smx_mutex_t mutex,
1027                                  double timeout)
1028 {
1029   smx_req_t req = SIMIX_req_mine();
1030
1031   req->call = REQ_COND_WAIT_TIMEOUT;
1032   req->cond_wait_timeout.cond = cond;
1033   req->cond_wait_timeout.mutex = mutex;
1034   req->cond_wait_timeout.timeout = timeout;
1035
1036   SIMIX_request_push();
1037 }
1038
1039 void SIMIX_req_cond_broadcast(smx_cond_t cond)
1040 {
1041   smx_req_t req = SIMIX_req_mine();
1042
1043   req->call = REQ_COND_BROADCAST;
1044   req->cond_broadcast.cond = cond;
1045
1046   SIMIX_request_push();
1047 }
1048
1049
1050 smx_sem_t SIMIX_req_sem_init(int capacity)
1051 {
1052   smx_req_t req = SIMIX_req_mine();
1053
1054   req->call = REQ_SEM_INIT;
1055   req->sem_init.capacity = capacity;
1056
1057   SIMIX_request_push();
1058   return req->sem_init.result;
1059 }
1060
1061 void SIMIX_req_sem_destroy(smx_sem_t sem)
1062 {
1063   smx_req_t req = SIMIX_req_mine();
1064
1065   req->call = REQ_SEM_DESTROY;
1066   req->sem_destroy.sem = sem;
1067
1068   SIMIX_request_push();
1069 }
1070
1071 void SIMIX_req_sem_release(smx_sem_t sem)
1072 {
1073   smx_req_t req = SIMIX_req_mine();
1074
1075   req->call = REQ_SEM_RELEASE;
1076   req->sem_release.sem = sem;
1077
1078   SIMIX_request_push();
1079 }
1080
1081 int SIMIX_req_sem_would_block(smx_sem_t sem)
1082 {
1083   smx_req_t req = SIMIX_req_mine();
1084
1085   req->call = REQ_SEM_WOULD_BLOCK;
1086   req->sem_would_block.sem = sem;
1087
1088   SIMIX_request_push();
1089   return req->sem_would_block.result;
1090 }
1091
1092 void SIMIX_req_sem_acquire(smx_sem_t sem)
1093 {
1094   smx_req_t req = SIMIX_req_mine();
1095
1096   req->call = REQ_SEM_ACQUIRE;
1097   req->sem_acquire.sem = sem;
1098
1099   SIMIX_request_push();
1100 }
1101
1102 void SIMIX_req_sem_acquire_timeout(smx_sem_t sem, double timeout)
1103 {
1104   smx_req_t req = SIMIX_req_mine();
1105
1106   req->call = REQ_SEM_ACQUIRE_TIMEOUT;
1107   req->sem_acquire_timeout.sem = sem;
1108   req->sem_acquire_timeout.timeout = timeout;
1109
1110   SIMIX_request_push();
1111 }
1112
1113 int SIMIX_req_sem_get_capacity(smx_sem_t sem)
1114 {
1115   smx_req_t req = SIMIX_req_mine();
1116
1117   req->call = REQ_SEM_GET_CAPACITY;
1118   req->sem_get_capacity.sem = sem;
1119
1120   SIMIX_request_push();
1121   return req->sem_get_capacity.result;
1122 }
1123 /* ************************************************************************** */
1124
1125 /** @brief returns a printable string representing the request kind */
1126 const char *SIMIX_request_name(int kind) {
1127   return request_names[kind];
1128 }