Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5b58220cc787b97cb951daa71b5a20ecdf6996c6
[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, smx_host_t 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.dest = dest;
386   SIMIX_request_push();
387 }
388
389 /**
390  * \brief Suspends a process.
391  *
392  * This function suspends the process by suspending the action
393  * it was waiting for completion.
394  *
395  * \param process a SIMIX process
396  */
397 void SIMIX_req_process_suspend(smx_process_t process)
398 {
399   xbt_assert(process, "Invalid parameters");
400
401   smx_req_t req = SIMIX_req_mine();
402
403   req->call = REQ_PROCESS_SUSPEND;
404   req->process_suspend.process = process;
405   SIMIX_request_push();
406 }
407
408 /**
409  * \brief Resumes a suspended process.
410  *
411  * This function resumes a suspended process by resuming the action
412  * it was waiting for completion.
413  *
414  * \param process a SIMIX process
415  */
416 void SIMIX_req_process_resume(smx_process_t process)
417 {
418   smx_req_t req = SIMIX_req_mine();
419
420   req->call = REQ_PROCESS_RESUME;
421   req->process_resume.process = process;
422   SIMIX_request_push();
423 }
424
425 /**
426  * \brief Returns the amount of SIMIX processes in the system
427  *
428  * Maestro internal process is not counted, only user code processes are
429  */
430 int SIMIX_req_process_count(void)
431 {
432   smx_req_t req = SIMIX_req_mine();
433
434   req->call = REQ_PROCESS_COUNT;
435   SIMIX_request_push();
436   return req->process_count.result;
437 }
438
439 /**
440  * \brief Return the user data of a #smx_process_t.
441  *
442  * 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.
443  * \param process SIMIX process
444  * \return A void pointer to the user data
445  */
446 void* SIMIX_req_process_get_data(smx_process_t process)
447 {
448   if (process == SIMIX_process_self()) {
449     /* avoid a request if this function is called by the process itself */
450     return SIMIX_process_self_get_data();
451   }
452
453   smx_req_t req = SIMIX_req_mine();
454
455   req->call = REQ_PROCESS_GET_DATA;
456   req->process_get_data.process = process;
457   SIMIX_request_push();
458   return req->process_get_data.result;
459 }
460
461 /**
462  * \brief Set the user data of a #m_process_t.
463  *
464  * 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.
465  * \param process SIMIX process
466  * \param data User data
467  */
468 void SIMIX_req_process_set_data(smx_process_t process, void *data)
469 {
470   if (process == SIMIX_process_self()) {
471     /* avoid a request if this function is called by the process itself */
472     SIMIX_process_self_set_data(data);
473   }
474   else {
475
476     smx_req_t req = SIMIX_req_mine();
477
478     req->call = REQ_PROCESS_SET_DATA;
479     req->process_set_data.process = process;
480     req->process_set_data.data = data;
481     SIMIX_request_push();
482   }
483 }
484
485 /**
486  * \brief Return the location on which an agent is running.
487  *
488  * 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.
489  * \param process SIMIX process
490  * \return SIMIX host
491  */
492 smx_host_t SIMIX_req_process_get_host(smx_process_t process)
493 {
494   smx_req_t req = SIMIX_req_mine();
495
496   req->call = REQ_PROCESS_GET_HOST;
497   req->process_get_host.process = process;
498   SIMIX_request_push();
499   return req->process_get_host.result;
500 }
501
502 /**
503  * \brief Return the name of an agent.
504  *
505  * This functions checks whether \a process is a valid pointer or not and return its name.
506  * \param process SIMIX process
507  * \return The process name
508  */
509 const char* SIMIX_req_process_get_name(smx_process_t process)
510 {
511   if (process == SIMIX_process_self()) {
512     /* avoid a request if this function is called by the process itself */
513     return process->name;
514   }
515
516   smx_req_t req = SIMIX_req_mine();
517
518   req->call = REQ_PROCESS_GET_NAME;
519   req->process_get_name.process = process;
520   SIMIX_request_push();
521   return req->process_get_name.result;
522 }
523
524 /**
525  * \brief Returns true if the process is suspended .
526  *
527  * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
528  * \param process SIMIX process
529  * \return 1, if the process is suspended, else 0.
530  */
531 int SIMIX_req_process_is_suspended(smx_process_t process)
532 {
533   smx_req_t req = SIMIX_req_mine();
534
535   req->call = REQ_PROCESS_IS_SUSPENDED;
536   req->process_is_suspended.process = process;
537   SIMIX_request_push();
538   return req->process_is_suspended.result;
539 }
540
541 /** \ingroup m_process_management
542  * \brief Return the properties
543  *
544  * This functions returns the properties associated with this process
545  */
546 xbt_dict_t SIMIX_req_process_get_properties(smx_process_t process)
547 {
548   smx_req_t req = SIMIX_req_mine();
549
550   req->call = REQ_PROCESS_GET_PROPERTIES;
551   req->process_get_properties.process = process;
552   SIMIX_request_push();
553   return req->process_get_properties.result;
554 }
555
556 /** \brief Creates a new sleep SIMIX action.
557  *
558  * This function creates a SURF action and allocates the data necessary
559  * to create the SIMIX action. It can raise a host_error exception if the
560  * host crashed. The default SIMIX name of the action is "sleep".
561  *
562  *      \param duration Time duration of the sleep.
563  *      \return A result telling whether the sleep was successful
564  */
565 e_smx_state_t SIMIX_req_process_sleep(double duration)
566 {
567   smx_req_t req = SIMIX_req_mine();
568
569   req->call = REQ_PROCESS_SLEEP;
570   req->process_sleep.duration = duration;
571   SIMIX_request_push();
572   return req->process_sleep.result;
573 }
574
575 /**
576  *  \brief Creates a new rendez-vous point
577  *  \param name The name of the rendez-vous point
578  *  \return The created rendez-vous point
579  */
580 smx_rdv_t SIMIX_req_rdv_create(const char *name)
581 {
582   smx_req_t req = SIMIX_req_mine();
583
584   req->call = REQ_RDV_CREATE;
585   req->rdv_create.name = name;
586
587   SIMIX_request_push();
588   return req->rdv_create.result;
589 }
590
591
592 /**
593  *  \brief Destroy a rendez-vous point
594  *  \param name The rendez-vous point to destroy
595  */
596 void SIMIX_req_rdv_destroy(smx_rdv_t rdv)
597 {
598   smx_req_t req = SIMIX_req_mine();
599
600   req->call = REQ_RDV_DESTROY;
601   req->rdv_destroy.rdv = rdv;
602
603   SIMIX_request_push();
604 }
605
606 smx_rdv_t SIMIX_req_rdv_get_by_name(const char *name)
607 {
608   xbt_assert(name != NULL, "Invalid parameter for SIMIX_req_rdv_get_by_name (name is NULL)");
609
610   /* FIXME: this is a horrible lost of performance, so we hack it out by
611    * skipping the request (for now). It won't work on distributed but
612    * probably we will change MSG for that. */
613 /*
614   smx_req_t req = SIMIX_req_mine();
615   req->call = REQ_RDV_GEY_BY_NAME;
616   req->rdv_get_by_name.name = name;
617   SIMIX_request_push();
618   return req->rdv_get_by_name.result;*/
619
620   return SIMIX_rdv_get_by_name(name);
621 }
622
623 /**
624  *  \brief counts the number of communication requests of a given host pending
625  *         on a rendez-vous point
626  *  \param rdv The rendez-vous point
627  *  \param host The host to be counted
628  *  \return The number of comm request pending in the rdv
629  */
630 int SIMIX_req_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
631 {
632   smx_req_t req = SIMIX_req_mine();
633
634   req->call = REQ_RDV_COMM_COUNT_BY_HOST;
635   req->rdv_comm_count_by_host.rdv = rdv;
636   req->rdv_comm_count_by_host.host = host;
637
638   SIMIX_request_push();
639   return req->rdv_comm_count_by_host.result;
640 }
641
642 /**
643  *  \brief returns the communication at the head of the rendez-vous
644  *  \param rdv The rendez-vous point
645  *  \return The communication or NULL if empty
646  */
647 smx_action_t SIMIX_req_rdv_get_head(smx_rdv_t rdv)
648 {
649   smx_req_t req = SIMIX_req_mine();
650
651   req->call = REQ_RDV_GET_HEAD;
652   req->rdv_get_head.rdv = rdv;
653
654   SIMIX_request_push();
655   return req->rdv_get_head.result;
656 }
657
658 void SIMIX_req_comm_send(smx_rdv_t rdv, double task_size, double rate,
659                          void *src_buff, size_t src_buff_size,
660                          int (*match_fun)(void *, void *), void *data,
661                          double timeout)
662 {
663   xbt_assert(rdv, "No rendez-vous point defined for send");
664
665   if (MC_IS_ENABLED) {
666     /* the model-checker wants two separate requests */
667     smx_action_t comm = SIMIX_req_comm_isend(rdv, task_size, rate,
668         src_buff, src_buff_size, match_fun, data, 0);
669     SIMIX_req_comm_wait(comm, timeout);
670   }
671   else {
672     smx_req_t req = SIMIX_req_mine();
673
674     req->call = REQ_COMM_SEND;
675     req->comm_send.rdv = rdv;
676     req->comm_send.task_size = task_size;
677     req->comm_send.rate = rate;
678     req->comm_send.src_buff = src_buff;
679     req->comm_send.src_buff_size = src_buff_size;
680     req->comm_send.match_fun = match_fun;
681     req->comm_send.data = data;
682     req->comm_send.timeout = timeout;
683
684     SIMIX_request_push();
685   }
686 }
687
688 smx_action_t SIMIX_req_comm_isend(smx_rdv_t rdv, double task_size, double rate,
689                               void *src_buff, size_t src_buff_size,
690                               int (*match_fun)(void *, void *), void *data,
691                               int detached)
692 {
693   xbt_assert(rdv, "No rendez-vous point defined for isend");
694
695   smx_req_t req = SIMIX_req_mine();
696
697   req->call = REQ_COMM_ISEND;
698   req->comm_isend.rdv = rdv;
699   req->comm_isend.task_size = task_size;
700   req->comm_isend.rate = rate;
701   req->comm_isend.src_buff = src_buff;
702   req->comm_isend.src_buff_size = src_buff_size;
703   req->comm_isend.match_fun = match_fun;
704   req->comm_isend.data = data;
705   req->comm_isend.detached = detached;
706
707   SIMIX_request_push();
708   return req->comm_isend.result;
709 }
710
711 void SIMIX_req_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
712                          int (*match_fun)(void *, void *), void *data, double timeout)
713 {
714   xbt_assert(rdv, "No rendez-vous point defined for recv");
715
716   if (MC_IS_ENABLED) {
717     /* the model-checker wants two separate requests */
718     smx_action_t comm = SIMIX_req_comm_irecv(rdv, dst_buff, dst_buff_size,
719         match_fun, data);
720     SIMIX_req_comm_wait(comm, timeout);
721   }
722   else {
723     smx_req_t req = SIMIX_req_mine();
724
725     req->call = REQ_COMM_RECV;
726     req->comm_recv.rdv = rdv;
727     req->comm_recv.dst_buff = dst_buff;
728     req->comm_recv.dst_buff_size = dst_buff_size;
729     req->comm_recv.match_fun = match_fun;
730     req->comm_recv.data = data;
731     req->comm_recv.timeout = timeout;
732
733     SIMIX_request_push();
734   }
735 }
736
737 smx_action_t SIMIX_req_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
738                                   int (*match_fun)(void *, void *), void *data)
739 {
740   xbt_assert(rdv, "No rendez-vous point defined for irecv");
741
742   smx_req_t req = SIMIX_req_mine();
743
744   req->call = REQ_COMM_IRECV;
745   req->comm_irecv.rdv = rdv;
746   req->comm_irecv.dst_buff = dst_buff;
747   req->comm_irecv.dst_buff_size = dst_buff_size;
748   req->comm_irecv.match_fun = match_fun;
749   req->comm_irecv.data = data;
750
751   SIMIX_request_push();
752   return req->comm_irecv.result;
753 }
754
755 void SIMIX_req_comm_destroy(smx_action_t comm)
756 {
757   xbt_assert(comm, "Invalid parameter");
758
759   /* FIXME remove this request type: comms are auto-destroyed now,
760    * but what happens with unfinished comms? */
761
762   /*
763   smx_req_t req = SIMIX_req_mine();
764
765   req->call = REQ_COMM_DESTROY;
766   req->comm_destroy.comm = comm;
767
768   SIMIX_request_push();
769   */
770 }
771
772 void SIMIX_req_comm_cancel(smx_action_t comm)
773 {
774   smx_req_t req = SIMIX_req_mine();
775
776   req->call = REQ_COMM_CANCEL;
777   req->comm_cancel.comm = comm;
778
779   SIMIX_request_push();
780 }
781
782 unsigned int SIMIX_req_comm_waitany(xbt_dynar_t comms)
783 {
784   smx_req_t req = SIMIX_req_mine();
785
786   req->call = REQ_COMM_WAITANY;
787   req->comm_waitany.comms = comms;
788
789   SIMIX_request_push();
790   return req->comm_waitany.result;
791 }
792
793 int SIMIX_req_comm_testany(xbt_dynar_t comms)
794 {
795   smx_req_t req = SIMIX_req_mine();
796   if (xbt_dynar_length(comms)==0)
797     return -1;
798
799   req->call = REQ_COMM_TESTANY;
800   req->comm_testany.comms = comms;
801
802   SIMIX_request_push();
803   return req->comm_testany.result;
804 }
805
806 void SIMIX_req_comm_wait(smx_action_t comm, double timeout)
807 {
808   smx_req_t req = SIMIX_req_mine();
809
810   req->call = REQ_COMM_WAIT;
811   req->comm_wait.comm = comm;
812   req->comm_wait.timeout = timeout;
813
814   SIMIX_request_push();
815 }
816
817 #ifdef HAVE_TRACING
818 /**
819  * \brief Set the category of an action.
820  *
821  * This functions changes the category only. It calls a surf function.
822  * \param execution The execution action
823  * \param category The tracing category
824  */
825 void SIMIX_req_set_category(smx_action_t action, const char *category)
826 {
827   if (category == NULL) {
828     return;
829   }
830
831   smx_req_t req = SIMIX_req_mine();
832
833   req->call = REQ_SET_CATEGORY;
834   req->set_category.action = action;
835   req->set_category.category = category;
836
837   SIMIX_request_push();
838 }
839 #endif
840
841 int SIMIX_req_comm_test(smx_action_t comm)
842 {
843   smx_req_t req = SIMIX_req_mine();
844
845   req->call = REQ_COMM_TEST;
846   req->comm_test.comm = comm;
847
848   SIMIX_request_push();
849   return req->comm_test.result;
850 }
851
852 double SIMIX_req_comm_get_remains(smx_action_t comm)
853 {
854   smx_req_t req = SIMIX_req_mine();
855
856   req->call = REQ_COMM_GET_REMAINS;
857   req->comm_get_remains.comm = comm;
858
859   SIMIX_request_push();
860   return req->comm_get_remains.result;
861 }
862
863 e_smx_state_t SIMIX_req_comm_get_state(smx_action_t comm)
864 {
865   smx_req_t req = SIMIX_req_mine();
866
867   req->call = REQ_COMM_GET_STATE;
868   req->comm_get_state.comm = comm;
869
870   SIMIX_request_push();
871   return req->comm_get_state.result;
872 }
873
874 void *SIMIX_req_comm_get_src_data(smx_action_t comm)
875 {
876   smx_req_t req = SIMIX_req_mine();
877
878   req->call = REQ_COMM_GET_SRC_DATA;
879   req->comm_get_src_data.comm = comm;
880
881   SIMIX_request_push();
882   return req->comm_get_src_data.result;
883 }
884
885 void *SIMIX_req_comm_get_dst_data(smx_action_t comm)
886 {
887   smx_req_t req = SIMIX_req_mine();
888
889   req->call = REQ_COMM_GET_DST_DATA;
890   req->comm_get_dst_data.comm = comm;
891
892   SIMIX_request_push();
893   return req->comm_get_dst_data.result;
894 }
895
896 smx_process_t SIMIX_req_comm_get_src_proc(smx_action_t comm)
897 {
898   smx_req_t req = SIMIX_req_mine();
899
900   req->call = REQ_COMM_GET_SRC_PROC;
901   req->comm_get_src_proc.comm = comm;
902
903   SIMIX_request_push();
904   return req->comm_get_src_proc.result;
905 }
906
907 smx_process_t SIMIX_req_comm_get_dst_proc(smx_action_t comm)
908 {
909   smx_req_t req = SIMIX_req_mine();
910
911   req->call = REQ_COMM_GET_DST_PROC;
912   req->comm_get_dst_proc.comm = comm;
913
914   SIMIX_request_push();
915   return req->comm_get_dst_proc.result;
916 }
917
918 #ifdef HAVE_LATENCY_BOUND_TRACKING
919 int SIMIX_req_comm_is_latency_bounded(smx_action_t comm)
920 {
921   smx_req_t req = SIMIX_req_mine();
922
923   req->call = REQ_COMM_IS_LATENCY_BOUNDED;
924   req->comm_is_latency_bounded.comm = comm;
925
926   SIMIX_request_push();
927   return req->comm_is_latency_bounded.result;
928 }
929 #endif
930
931 smx_mutex_t SIMIX_req_mutex_init(void)
932 {
933   smx_req_t req = SIMIX_req_mine();
934
935   req->call = REQ_MUTEX_INIT;
936
937   SIMIX_request_push();
938   return req->mutex_init.result;
939 }
940
941 void SIMIX_req_mutex_destroy(smx_mutex_t mutex)
942 {
943   smx_req_t req = SIMIX_req_mine();
944
945   req->call = REQ_MUTEX_DESTROY;
946   req->mutex_destroy.mutex = mutex;
947
948   SIMIX_request_push();
949 }
950
951 void SIMIX_req_mutex_lock(smx_mutex_t mutex)
952 {
953   smx_req_t req = SIMIX_req_mine();
954
955   req->call = REQ_MUTEX_LOCK;
956   req->mutex_lock.mutex = mutex;
957
958   SIMIX_request_push();
959 }
960
961 int SIMIX_req_mutex_trylock(smx_mutex_t mutex)
962 {
963   smx_req_t req = SIMIX_req_mine();
964
965   req->call = REQ_MUTEX_TRYLOCK;
966   req->mutex_trylock.mutex = mutex;
967
968   SIMIX_request_push();
969   return req->mutex_trylock.result;
970 }
971
972 void SIMIX_req_mutex_unlock(smx_mutex_t mutex)
973 {
974   smx_req_t req = SIMIX_req_mine();
975
976   req->call = REQ_MUTEX_UNLOCK;
977   req->mutex_unlock.mutex = mutex;
978
979   SIMIX_request_push();
980 }
981
982
983 smx_cond_t SIMIX_req_cond_init(void)
984 {
985   smx_req_t req = SIMIX_req_mine();
986
987   req->call = REQ_COND_INIT;
988
989   SIMIX_request_push();
990   return req->cond_init.result;
991 }
992
993 void SIMIX_req_cond_destroy(smx_cond_t cond)
994 {
995   smx_req_t req = SIMIX_req_mine();
996
997   req->call = REQ_COND_DESTROY;
998   req->cond_destroy.cond = cond;
999
1000   SIMIX_request_push();
1001 }
1002
1003 void SIMIX_req_cond_signal(smx_cond_t cond)
1004 {
1005   smx_req_t req = SIMIX_req_mine();
1006
1007   req->call = REQ_COND_SIGNAL;
1008   req->cond_signal.cond = cond;
1009
1010   SIMIX_request_push();
1011 }
1012
1013 void SIMIX_req_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
1014 {
1015   smx_req_t req = SIMIX_req_mine();
1016
1017   req->call = REQ_COND_WAIT;
1018   req->cond_wait.cond = cond;
1019   req->cond_wait.mutex = mutex;
1020
1021   SIMIX_request_push();
1022 }
1023
1024 void SIMIX_req_cond_wait_timeout(smx_cond_t cond,
1025                                  smx_mutex_t mutex,
1026                                  double timeout)
1027 {
1028   smx_req_t req = SIMIX_req_mine();
1029
1030   req->call = REQ_COND_WAIT_TIMEOUT;
1031   req->cond_wait_timeout.cond = cond;
1032   req->cond_wait_timeout.mutex = mutex;
1033   req->cond_wait_timeout.timeout = timeout;
1034
1035   SIMIX_request_push();
1036 }
1037
1038 void SIMIX_req_cond_broadcast(smx_cond_t cond)
1039 {
1040   smx_req_t req = SIMIX_req_mine();
1041
1042   req->call = REQ_COND_BROADCAST;
1043   req->cond_broadcast.cond = cond;
1044
1045   SIMIX_request_push();
1046 }
1047
1048
1049 smx_sem_t SIMIX_req_sem_init(int capacity)
1050 {
1051   smx_req_t req = SIMIX_req_mine();
1052
1053   req->call = REQ_SEM_INIT;
1054   req->sem_init.capacity = capacity;
1055
1056   SIMIX_request_push();
1057   return req->sem_init.result;
1058 }
1059
1060 void SIMIX_req_sem_destroy(smx_sem_t sem)
1061 {
1062   smx_req_t req = SIMIX_req_mine();
1063
1064   req->call = REQ_SEM_DESTROY;
1065   req->sem_destroy.sem = sem;
1066
1067   SIMIX_request_push();
1068 }
1069
1070 void SIMIX_req_sem_release(smx_sem_t sem)
1071 {
1072   smx_req_t req = SIMIX_req_mine();
1073
1074   req->call = REQ_SEM_RELEASE;
1075   req->sem_release.sem = sem;
1076
1077   SIMIX_request_push();
1078 }
1079
1080 int SIMIX_req_sem_would_block(smx_sem_t sem)
1081 {
1082   smx_req_t req = SIMIX_req_mine();
1083
1084   req->call = REQ_SEM_WOULD_BLOCK;
1085   req->sem_would_block.sem = sem;
1086
1087   SIMIX_request_push();
1088   return req->sem_would_block.result;
1089 }
1090
1091 void SIMIX_req_sem_acquire(smx_sem_t sem)
1092 {
1093   smx_req_t req = SIMIX_req_mine();
1094
1095   req->call = REQ_SEM_ACQUIRE;
1096   req->sem_acquire.sem = sem;
1097
1098   SIMIX_request_push();
1099 }
1100
1101 void SIMIX_req_sem_acquire_timeout(smx_sem_t sem, double timeout)
1102 {
1103   smx_req_t req = SIMIX_req_mine();
1104
1105   req->call = REQ_SEM_ACQUIRE_TIMEOUT;
1106   req->sem_acquire_timeout.sem = sem;
1107   req->sem_acquire_timeout.timeout = timeout;
1108
1109   SIMIX_request_push();
1110 }
1111
1112 int SIMIX_req_sem_get_capacity(smx_sem_t sem)
1113 {
1114   smx_req_t req = SIMIX_req_mine();
1115
1116   req->call = REQ_SEM_GET_CAPACITY;
1117   req->sem_get_capacity.sem = sem;
1118
1119   SIMIX_request_push();
1120   return req->sem_get_capacity.result;
1121 }
1122 /* ************************************************************************** */
1123
1124 /** @brief returns a printable string representing the request kind */
1125 const char *SIMIX_request_name(int kind) {
1126   return request_names[kind];
1127 }