Logo AND Algorithmique Numérique Distribuée

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