Logo AND Algorithmique Numérique Distribuée

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