Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add MSG_host_on and MSG_host_off
[simgrid.git] / src / simix / smx_user.c
1 /* smx_user.c - public interface to simix                                   */
2
3 /* Copyright (c) 2010-2012. Da SimGrid team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "smx_private.h"
9 #include "mc/mc.h"
10 #include "xbt/ex.h"
11 #include <math.h>         /* isfinite() */
12
13 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
14
15 /* generate strings from the enumeration values */
16 static const char* simcall_names[] = {
17 SIMCALL_LIST(SIMCALL_STRING_TYPE, SIMCALL_SEP_COMMA)
18 [SIMCALL_NONE] = "NONE"
19 };
20
21 SIMCALL_LIST(SIMCALL_FUNC, SIMCALL_SEP_NOTHING)
22
23 /**
24  * \ingroup simix_host_management
25  * \brief Returns a host given its name.
26  *
27  * \param name The name of the host to get
28  * \return The corresponding host
29  */
30 smx_host_t simcall_host_get_by_name(const char *name)
31 {
32   return simcall_BODY_host_get_by_name(name);
33 }
34
35 /**
36  * \ingroup simix_host_management
37  * \brief Returns the name of a host.
38  *
39  * \param host A SIMIX host
40  * \return The name of this host
41  */
42 const char* simcall_host_get_name(smx_host_t host)
43 {
44   return simcall_BODY_host_get_name(host);
45 }
46
47 /**
48  * \ingroup simix_host_management
49  * \brief Start the host if it is off
50  *
51  * \param host A SIMIX host
52  */
53 void simcall_host_on(smx_host_t host)
54 {
55   simcall_BODY_host_on(host);
56 }
57
58 /**
59  * \ingroup simix_host_management
60  * \brief Stop the host if it is on
61  *
62  * \param host A SIMIX host
63  */
64 void simcall_host_off(smx_host_t host)
65 {
66   simcall_BODY_host_off(host);
67 }
68
69 /**
70  * \ingroup simix_host_management
71  * \brief Returns a dict of the properties assigned to a host.
72  *
73  * \param host A host
74  * \return The properties of this host
75  */
76 xbt_dict_t simcall_host_get_properties(smx_host_t host)
77 {
78   return simcall_BODY_host_get_properties(host);
79 }
80
81 /**
82  * \ingroup simix_host_management
83  * \brief Returns a dict of the properties assigned to a router or AS.
84  *
85  * \param name The name of the router or AS
86  * \return The properties
87  */
88 xbt_dict_t simcall_asr_get_properties(const char *name)
89 {
90   return simcall_BODY_asr_get_properties(name);
91 }
92
93
94 /**
95  * \ingroup simix_host_management
96  * \brief Returns the speed of the processor.
97  *
98  * The speed returned does not take into account the current load on the machine.
99  * \param host A SIMIX host
100  * \return The speed of this host (in Mflop/s)
101  */
102 double simcall_host_get_speed(smx_host_t host)
103 {
104   return simcall_BODY_host_get_speed(host);
105 }
106
107 /**
108  * \ingroup simix_host_management
109  * \brief Returns the available speed of the processor.
110  *
111  * \return Speed currently available (in Mflop/s)
112  */
113 double simcall_host_get_available_speed(smx_host_t host)
114 {
115   return simcall_BODY_host_get_available_speed(host);
116 }
117
118 /**
119  * \ingroup simix_host_management
120  * \brief Returns the state of a host.
121  *
122  * Two states are possible: 1 if the host is active or 0 if it has crashed.
123  * \param host A SIMIX host
124  * \return 1 if the host is available, 0 otherwise
125  */
126 int simcall_host_get_state(smx_host_t host)
127 {
128   return simcall_BODY_host_get_state(host);
129 }
130
131 /**
132  * \ingroup simix_host_management
133  * \brief Returns the user data associated to a host.
134  *
135  * \param host SIMIX host
136  * \return the user data of this host
137  */
138 void* simcall_host_get_data(smx_host_t host)
139 {
140   return simcall_BODY_host_get_data(host);
141 }
142
143 /**
144  * \ingroup simix_host_management
145  * \brief Sets the user data associated to a host.
146  *
147  * The host must not have previous user data associated to it.
148  * \param host A SIMIX host
149  * \param data The user data to set
150  */
151 void simcall_host_set_data(smx_host_t host, void *data)
152 {
153   simcall_host_set_data(host, data);
154 }
155
156 /**
157  * \ingroup simix_host_management
158  * \brief Creates an action that executes some computation of an host.
159  *
160  * This function creates a SURF action and allocates the data necessary
161  * to create the SIMIX action. It can raise a host_error exception if the host crashed.
162  *
163  * \param name Name of the execution action to create
164  * \param host SIMIX host where the action will be executed
165  * \param computation_amount amount Computation amount (in bytes)
166  * \param priority computation priority
167  * \return A new SIMIX execution action
168  */
169
170 smx_action_t simcall_host_execute(const char *name, smx_host_t host,
171                                     double computation_amount,
172                                     double priority, double bound)
173 {
174   /* checking for infinite values */
175   xbt_assert(isfinite(computation_amount), "computation_amount is not finite!");
176   xbt_assert(isfinite(priority), "priority is not finite!");
177   
178   return simcall_BODY_host_execute(name, host, computation_amount, priority, bound);
179 }
180
181 /**
182  * \ingroup simix_host_management
183  * \brief Creates an action that may involve parallel computation on
184  * several hosts and communication between them.
185  *
186  * \param name Name of the execution action to create
187  * \param host_nb Number of hosts where the action will be executed
188  * \param host_list Array (of size host_nb) of hosts where the action will be executed
189  * \param computation_amount Array (of size host_nb) of computation amount of hosts (in bytes)
190  * \param communication_amount Array (of size host_nb * host_nb) representing the communication
191  * amount between each pair of hosts
192  * \param amount the SURF action amount
193  * \param rate the SURF action rate
194  * \return A new SIMIX execution action
195  */
196 smx_action_t simcall_host_parallel_execute(const char *name,
197                                          int host_nb,
198                                          smx_host_t *host_list,
199                                          double *computation_amount,
200                                          double *communication_amount,
201                                          double amount,
202                                          double rate)
203 {
204   int i,j;
205   /* checking for infinite values */
206   for (i = 0 ; i < host_nb ; ++i) {
207      xbt_assert(isfinite(computation_amount[i]), "computation_amount[%d] is not finite!", i);
208      for (j = 0 ; j < host_nb ; ++j) {
209         xbt_assert(isfinite(communication_amount[i + host_nb * j]), 
210              "communication_amount[%d+%d*%d] is not finite!", i, host_nb, j);
211      }   
212   }   
213  
214   xbt_assert(isfinite(amount), "amount is not finite!");
215   xbt_assert(isfinite(rate), "rate is not finite!");
216   
217   return simcall_BODY_host_parallel_execute(name, host_nb, host_list,
218                                             computation_amount,
219                                             communication_amount,
220                                             amount, rate);
221
222 }
223
224 /**
225  * \ingroup simix_host_management
226  * \brief Destroys an execution action.
227  *
228  * Destroys an action, freing its memory. This function cannot be called if there are a conditional waiting for it.
229  * \param execution The execution action to destroy
230  */
231 void simcall_host_execution_destroy(smx_action_t execution)
232 {
233   simcall_BODY_host_execution_destroy(execution);
234 }
235
236 /**
237  * \ingroup simix_host_management
238  * \brief Cancels an execution action.
239  *
240  * This functions stops the execution. It calls a surf function.
241  * \param execution The execution action to cancel
242  */
243 void simcall_host_execution_cancel(smx_action_t execution)
244 {
245   simcall_BODY_host_execution_cancel(execution);
246 }
247
248 /**
249  * \ingroup simix_host_management
250  * \brief Returns how much of an execution action remains to be done.
251  *
252  * \param execution The execution action
253  * \return The remaining amount
254  */
255 double simcall_host_execution_get_remains(smx_action_t execution)
256 {
257   return simcall_BODY_host_execution_get_remains(execution);
258 }
259
260 /**
261  * \ingroup simix_host_management
262  * \brief Returns the state of an execution action.
263  *
264  * \param execution The execution action
265  * \return The state
266  */
267 e_smx_state_t simcall_host_execution_get_state(smx_action_t execution)
268 {
269   return simcall_BODY_host_execution_get_state(execution);
270 }
271
272 /**
273  * \ingroup simix_host_management
274  * \brief Changes the priority of an execution action.
275  *
276  * This functions changes the priority only. It calls a surf function.
277  * \param execution The execution action
278  * \param priority The new priority
279  */
280 void simcall_host_execution_set_priority(smx_action_t execution, double priority)
281 {
282   /* checking for infinite values */
283   xbt_assert(isfinite(priority), "priority is not finite!");
284   
285   simcall_BODY_host_execution_set_priority(execution, priority);
286 }
287
288 /**
289  * \ingroup simix_host_management
290  * \brief Changes the capping (the maximum CPU utilization) of an execution action.
291  *
292  * This functions changes the capping only. It calls a surf function.
293  * \param execution The execution action
294  * \param bound The new bound
295  */
296 void simcall_host_execution_set_bound(smx_action_t execution, double bound)
297 {
298   simcall_BODY_host_execution_set_bound(execution, bound);
299 }
300
301 /**
302  * \ingroup simix_host_management
303  * \brief Waits for the completion of an execution action and destroy it.
304  *
305  * \param execution The execution action
306  */
307 e_smx_state_t simcall_host_execution_wait(smx_action_t execution)
308 {
309   return simcall_BODY_host_execution_wait(execution);
310 }
311
312
313 /**
314  * \ingroup simix_vm_management
315  * \brief Create a VM on the given physical host.
316  *
317  * \param name VM name
318  * \param host Physical host
319  *
320  * \return The host object of the VM
321  */
322 void* simcall_vm_create(const char *name, smx_host_t phys_host){
323   /* will jump to SIMIX_pre_vm_create() in src/simix/smx_smurf_private.h */
324   return simcall_BODY_vm_create(name, phys_host);
325 }
326
327 /**
328  * \ingroup simix_vm_management
329  * \brief Start the given VM to the given physical host
330  *
331  * \param vm VM
332  */
333 void simcall_vm_start(smx_host_t vm)
334 {
335   /* will jump to SIMIX_pre_vm_start in src/simix/smx_smurf_private.h */
336   simcall_BODY_vm_start(vm);
337 }
338
339 /**
340  * \ingroup simix_vm_management
341  * \brief Get the state of the given VM
342  *
343  * \param vm VM
344  * \return The state of the VM
345  */
346 int simcall_vm_get_state(smx_host_t vm)
347 {
348   /* will jump to SIMIX_pre_vm_get_state in src/simix/smx_smurf_private.h */
349   return simcall_BODY_vm_get_state(vm);
350 }
351
352 /**
353  * \ingroup simix_vm_management
354  * \brief Get the name of the physical host on which the given VM runs.
355  *
356  * \param vm VM
357  * \return The name of the physical host
358  */
359 void *simcall_vm_get_pm(smx_host_t vm)
360 {
361   /* will jump to SIMIX_pre_vm_migrate in src/simix/smx_smurf_private.h */
362   return simcall_BODY_vm_get_pm(vm);
363 }
364
365 void simcall_vm_set_bound(smx_host_t vm, double bound)
366 {
367   /* will jump to SIMIX_pre_vm_set_bound in src/simix/smx_smurf_private.h */
368   simcall_BODY_vm_set_bound(vm, bound);
369 }
370
371 void simcall_host_get_params(smx_host_t vm, ws_params_t params)
372 {
373   /* will jump to SIMIX_pre_host_get_params in src/simix/smx_smurf_private.h */
374   simcall_BODY_host_get_params(vm, params);
375 }
376
377 void simcall_host_set_params(smx_host_t vm, ws_params_t params)
378 {
379   /* will jump to SIMIX_pre_host_set_params in src/simix/smx_smurf_private.h */
380   simcall_BODY_host_set_params(vm, params);
381 }
382
383 /**
384  * \ingroup simix_vm_management
385  * \brief Migrate the given VM to the given physical host
386  *
387  * \param vm VM
388  * \param host Destination physical host
389  */
390 void simcall_vm_migrate(smx_host_t vm, smx_host_t host)
391 {
392   /* will jump to SIMIX_pre_vm_migrate in src/simix/smx_smurf_private.h */
393   simcall_BODY_vm_migrate(vm, host);
394 }
395
396 /**
397  * \ingroup simix_vm_management
398  * \brief Suspend the given VM
399  *
400  * \param vm VM
401  */
402 void simcall_vm_suspend(smx_host_t vm)
403 {
404   /* will jump to SIMIX_pre_vm_suspend in src/simix/smx_smurf_private.h */
405   simcall_BODY_vm_suspend(vm);
406 }
407
408 /**
409  * \ingroup simix_vm_management
410  * \brief Resume the given VM
411  *
412  * \param vm VM
413  */
414 void simcall_vm_resume(smx_host_t vm)
415 {
416   /* will jump to SIMIX_pre_vm_resume in src/simix/smx_smurf_private.h */
417   simcall_BODY_vm_resume(vm);
418 }
419
420 /**
421  * \ingroup simix_vm_management
422  * \brief Save the given VM
423  *
424  * \param vm VM
425  */
426 void simcall_vm_save(smx_host_t vm)
427 {
428   /* will jump to SIMIX_pre_vm_save in src/simix/smx_smurf_private.h */
429   simcall_BODY_vm_save(vm);
430 }
431
432 /**
433  * \ingroup simix_vm_management
434  * \brief Restore the given VM
435  *
436  * \param vm VM
437  */
438 void simcall_vm_restore(smx_host_t vm)
439 {
440   /* will jump to SIMIX_pre_vm_restore in src/simix/smx_smurf_private.h */
441   simcall_BODY_vm_restore(vm);
442 }
443
444 /**
445  * \ingroup simix_vm_management
446  * \brief Shutdown the given VM
447  *
448  * \param vm VM
449  */
450 void simcall_vm_shutdown(smx_host_t vm)
451 {
452   /* will jump to SIMIX_pre_vm_shutdown in src/simix/smx_smurf_private.h */
453   simcall_BODY_vm_shutdown(vm);
454 }
455
456 /**
457  * \ingroup simix_vm_management
458  * \brief Destroy the given VM
459  *
460  * \param vm VM
461  */
462 void simcall_vm_destroy(smx_host_t vm)
463 {
464    /* will jump to SIMIX_pre_vm_destroy in src/simix/smx_smurf_private.h */
465   simcall_BODY_vm_destroy(vm);
466 }
467
468
469 /**
470  * \ingroup simix_process_management
471  * \brief Creates and runs a new SIMIX process.
472  *
473  * The structure and the corresponding thread are created and put in the list of ready processes.
474  *
475  * \param process the process created will be stored in this pointer
476  * \param name a name for the process. It is for user-level information and can be NULL.
477  * \param code the main function of the process
478  * \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.
479  * It can be retrieved with the function \ref simcall_process_get_data.
480  * \param hostname name of the host where the new agent is executed.
481  * \param kill_time time when the process is killed
482  * \param argc first argument passed to \a code
483  * \param argv second argument passed to \a code
484  * \param properties the properties of the process
485  * \param auto_restart either it is autorestarting or not.
486  */
487 void simcall_process_create(smx_process_t *process, const char *name,
488                               xbt_main_func_t code,
489                               void *data,
490                               const char *hostname,
491                               double kill_time,
492                               int argc, char **argv,
493                               xbt_dict_t properties,
494                               int auto_restart)
495 {
496   simcall_BODY_process_create(process, name, code, data, hostname,
497                               kill_time, argc, argv, properties,
498                               auto_restart);
499 }
500
501 /**
502  * \ingroup simix_process_management
503  * \brief Kills a SIMIX process.
504  *
505  * This function simply kills a  process.
506  *
507  * \param process poor victim
508  */
509 void simcall_process_kill(smx_process_t process)
510 {
511   simcall_BODY_process_kill(process);
512 }
513
514 /**
515  * \ingroup simix_process_management
516  * \brief Kills all SIMIX processes.
517  */
518 void simcall_process_killall(int reset_pid)
519 {
520   simcall_BODY_process_killall(reset_pid);
521 }
522
523 /**
524  * \ingroup simix_process_management
525  * \brief Cleans up a SIMIX process.
526  * \param process poor victim (must have already been killed)
527  */
528 void simcall_process_cleanup(smx_process_t process)
529 {
530   simcall_BODY_process_cleanup(process);
531 }
532
533 /**
534  * \ingroup simix_process_management
535  * \brief Migrates an agent to another location.
536  *
537  * This function changes the value of the host on which \a process is running.
538  *
539  * \param process the process to migrate
540  * \param dest name of the new host
541  */
542 void simcall_process_change_host(smx_process_t process, smx_host_t dest)
543 {
544   simcall_BODY_process_change_host(process, dest);
545 }
546
547 /**
548  * \ingroup simix_process_management
549  * \brief Suspends a process.
550  *
551  * This function suspends the process by suspending the action
552  * it was waiting for completion.
553  *
554  * \param process a SIMIX process
555  */
556 void simcall_process_suspend(smx_process_t process)
557 {
558   xbt_assert(process, "Invalid parameters");
559
560   simcall_BODY_process_suspend(process);
561 }
562
563 /**
564  * \ingroup simix_process_management
565  * \brief Resumes a suspended process.
566  *
567  * This function resumes a suspended process by resuming the action
568  * it was waiting for completion.
569  *
570  * \param process a SIMIX process
571  */
572 void simcall_process_resume(smx_process_t process)
573 {
574   simcall_BODY_process_resume(process);
575 }
576
577 /**
578  * \ingroup simix_process_management
579  * \brief Returns the amount of SIMIX processes in the system
580  *
581  * Maestro internal process is not counted, only user code processes are
582  */
583 int simcall_process_count(void)
584 {
585   return simcall_BODY_process_count();
586 }
587
588 /**
589  * \ingroup simix_process_management
590  * \brief Return the PID of a #smx_process_t.
591  * \param process a SIMIX process
592  * \return the PID of this process
593  */
594 int simcall_process_get_PID(smx_process_t process)
595 {
596   if (process == SIMIX_process_self()) {
597     /* avoid a simcall if this function is called by the process itself */
598     return SIMIX_process_get_PID(process);
599   }
600
601   return simcall_BODY_process_get_PID(process);
602 }
603
604 /**
605  * \ingroup simix_process_management
606  * \brief Return the parent PID of a #smx_process_t.
607  * \param process a SIMIX process
608  * \return the PID of this process parenrt
609  */
610 int simcall_process_get_PPID(smx_process_t process)
611 {
612   if (process == SIMIX_process_self()) {
613     /* avoid a simcall if this function is called by the process itself */
614     return SIMIX_process_get_PPID(process);
615   }
616
617   return simcall_BODY_process_get_PPID(process);
618 }
619
620 /**
621  * \ingroup simix_process_management
622  * \brief Return the user data of a #smx_process_t.
623  * \param process a SIMIX process
624  * \return the user data of this process
625  */
626 void* simcall_process_get_data(smx_process_t process)
627 {
628   if (process == SIMIX_process_self()) {
629     /* avoid a simcall if this function is called by the process itself */
630     return SIMIX_process_get_data(process);
631   }
632
633   return simcall_BODY_process_get_data(process);
634 }
635
636 /**
637  * \ingroup simix_process_management
638  * \brief Set the user data of a #smx_process_t.
639  *
640  * This functions sets the user data associated to \a process.
641  * \param process SIMIX process
642  * \param data User data
643  */
644 void simcall_process_set_data(smx_process_t process, void *data)
645 {
646   if (process == SIMIX_process_self()) {
647     /* avoid a simcall if this function is called by the process itself */
648     SIMIX_process_self_set_data(process, data);
649   }
650   else {
651     simcall_BODY_process_set_data(process, data);
652   }
653 }
654
655 /**
656  * \ingroup simix_process_management
657  * \brief Set the kill time of a process.
658  * \param process a process
659  * \param kill_time a double
660  */
661 void simcall_process_set_kill_time(smx_process_t process, double kill_time)
662 {
663
664   if (kill_time > SIMIX_get_clock()) {
665     if (simix_global->kill_process_function) {
666       XBT_DEBUG("Set kill time %f for process %s(%s)",kill_time, process->name,
667           sg_host_name(process->smx_host));
668       SIMIX_timer_set(kill_time, simix_global->kill_process_function, process);
669     }
670   }
671 }
672
673 /**
674  * \ingroup simix_process_management
675  * \brief Return the location on which an agent is running.
676  *
677  * This functions returns the smx_host_t corresponding to the location on which
678  * \a process is running.
679  * \param process SIMIX process
680  * \return SIMIX host
681  */
682 smx_host_t simcall_process_get_host(smx_process_t process)
683 {
684   return simcall_BODY_process_get_host(process);
685 }
686
687 /**
688  * \ingroup simix_process_management
689  * \brief Return the name of an agent.
690  *
691  * This functions checks whether \a process is a valid pointer or not and return its name.
692  * \param process SIMIX process
693  * \return The process name
694  */
695 const char* simcall_process_get_name(smx_process_t process)
696 {
697   if (process == SIMIX_process_self()) {
698     /* avoid a simcall if this function is called by the process itself */
699     return process->name;
700   }
701   return simcall_BODY_process_get_name(process);
702 }
703
704 /**
705  * \ingroup simix_process_management
706  * \brief Returns true if the process is suspended .
707  *
708  * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
709  * \param process SIMIX process
710  * \return 1, if the process is suspended, else 0.
711  */
712 int simcall_process_is_suspended(smx_process_t process)
713 {
714   return  simcall_BODY_process_is_suspended(process);
715 }
716
717 /**
718  * \ingroup simix_process_management
719  * \brief Return the properties
720  *
721  * This functions returns the properties associated with this process
722  */
723 xbt_dict_t simcall_process_get_properties(smx_process_t process)
724 {
725   return simcall_BODY_process_get_properties(process);
726 }
727 /**
728  * \ingroup simix_process_management
729  * \brief Add an on_exit function
730  * Add an on_exit function which will be executed when the process exits/is killed.
731  */
732 XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
733 {
734   simcall_BODY_process_on_exit(process, fun, data);
735 }
736 /**
737  * \ingroup simix_process_management
738  * \brief Sets the process to be auto-restarted or not by SIMIX when its host comes back up.
739  * Will restart the process when the host comes back up if auto_restart is set to 1.
740  */
741
742 XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart)
743 {
744   simcall_BODY_process_auto_restart_set(process, auto_restart);
745 }
746
747 /**
748  * \ingroup simix_process_management
749  * \brief Restarts the process, killing it and starting it again from scratch.
750  */
751 XBT_PUBLIC(smx_process_t) simcall_process_restart(smx_process_t process)
752 {
753   return simcall_BODY_process_restart(process);
754 }
755 /**
756  * \ingroup simix_process_management
757  * \brief Creates a new sleep SIMIX action.
758  *
759  * This function creates a SURF action and allocates the data necessary
760  * to create the SIMIX action. It can raise a host_error exception if the
761  * host crashed. The default SIMIX name of the action is "sleep".
762  *
763  *   \param duration Time duration of the sleep.
764  *   \return A result telling whether the sleep was successful
765  */
766 e_smx_state_t simcall_process_sleep(double duration)
767 {
768   /* checking for infinite values */
769   xbt_assert(isfinite(duration), "duration is not finite!");
770   return simcall_BODY_process_sleep(duration);
771 }
772
773 /**
774  *  \ingroup simix_rdv_management
775  *  \brief Creates a new rendez-vous point
776  *  \param name The name of the rendez-vous point
777  *  \return The created rendez-vous point
778  */
779 smx_rdv_t simcall_rdv_create(const char *name)
780 {
781   return simcall_BODY_rdv_create(name);
782 }
783
784
785 /**
786  *  \ingroup simix_rdv_management
787  *  \brief Destroy a rendez-vous point
788  *  \param rdv The rendez-vous point to destroy
789  */
790 void simcall_rdv_destroy(smx_rdv_t rdv)
791 {
792   simcall_BODY_rdv_destroy(rdv);
793 }
794 /**
795  *  \ingroup simix_rdv_management
796  *  \brief Returns a rendez-vous point knowing its name
797  */
798 smx_rdv_t simcall_rdv_get_by_name(const char *name)
799 {
800   xbt_assert(name != NULL, "Invalid parameter for simcall_rdv_get_by_name (name is NULL)");
801
802   /* FIXME: this is a horrible loss of performance, so we hack it out by
803    * skipping the simcall (for now). It works in parallel, it won't work on
804    * distributed but probably we will change MSG for that. */
805
806   /*
807   smx_simcall_t simcall = simcall_mine();
808   simcall->call = SIMCALL_RDV_GEY_BY_NAME;
809   simcall->rdv_get_by_name.name = name;
810   SIMIX_simcall_push(simcall->issuer);
811   return simcall->rdv_get_by_name.result;*/
812
813   return SIMIX_rdv_get_by_name(name);
814 }
815
816 /**
817  *  \ingroup simix_rdv_management
818  *  \brief Counts the number of communication actions of a given host pending
819  *         on a rendez-vous point.
820  *  \param rdv The rendez-vous point
821  *  \param host The host to be counted
822  *  \return The number of comm actions pending in the rdv
823  */
824 int simcall_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
825 {
826   return simcall_BODY_rdv_comm_count_by_host(rdv, host);
827 }
828
829 /**
830  *  \ingroup simix_rdv_management
831  *  \brief returns the communication at the head of the rendez-vous
832  *  \param rdv The rendez-vous point
833  *  \return The communication or NULL if empty
834  */
835 smx_action_t simcall_rdv_get_head(smx_rdv_t rdv)
836 {
837   return simcall_BODY_rdv_get_head(rdv);
838 }
839
840 void simcall_rdv_set_receiver(smx_rdv_t rdv, smx_process_t process)
841 {
842   simcall_BODY_rdv_set_receiver(rdv, process);
843 }
844
845 smx_process_t simcall_rdv_get_receiver(smx_rdv_t rdv)
846 {
847   return simcall_BODY_rdv_get_receiver(rdv);
848 }
849
850 /**
851  * \ingroup simix_comm_management
852  */
853 void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
854                          void *src_buff, size_t src_buff_size,
855                          int (*match_fun)(void *, void *, smx_action_t), void *data,
856                          double timeout)
857 {
858   /* checking for infinite values */
859   xbt_assert(isfinite(task_size), "task_size is not finite!");
860   xbt_assert(isfinite(rate), "rate is not finite!");
861   xbt_assert(isfinite(timeout), "timeout is not finite!");
862   
863   xbt_assert(rdv, "No rendez-vous point defined for send");
864
865   if (MC_is_active()) {
866     /* the model-checker wants two separate simcalls */
867     smx_action_t comm = simcall_comm_isend(rdv, task_size, rate,
868         src_buff, src_buff_size, match_fun, NULL, data, 0);
869     simcall_comm_wait(comm, timeout);
870   }
871   else {
872     simcall_BODY_comm_send(rdv, task_size, rate, src_buff, src_buff_size,
873                          match_fun, data, timeout);
874   }
875 }
876
877 /**
878  * \ingroup simix_comm_management
879  */
880 smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
881                               void *src_buff, size_t src_buff_size,
882                               int (*match_fun)(void *, void *, smx_action_t),
883                               void (*clean_fun)(void *),
884                               void *data,
885                               int detached)
886 {
887   /* checking for infinite values */
888   xbt_assert(isfinite(task_size), "task_size is not finite!");
889   xbt_assert(isfinite(rate), "rate is not finite!");
890   
891   xbt_assert(rdv, "No rendez-vous point defined for isend");
892
893   return simcall_BODY_comm_isend(rdv, task_size, rate, src_buff,
894                                  src_buff_size, match_fun,
895                                  clean_fun, data, detached);
896 }
897 /**
898  * \ingroup simix_comm_management
899  */
900 void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
901                          int (*match_fun)(void *, void *, smx_action_t), void *data, double timeout)
902 {
903   xbt_assert(isfinite(timeout), "timeout is not finite!");
904   xbt_assert(rdv, "No rendez-vous point defined for recv");
905
906   if (MC_is_active()) {
907     /* the model-checker wants two separate simcalls */
908     smx_action_t comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
909         match_fun, data);
910     simcall_comm_wait(comm, timeout);
911   }
912   else {
913     simcall_BODY_comm_recv(rdv, dst_buff, dst_buff_size,
914                            match_fun, data, timeout);
915   }
916 }
917 /**
918  * \ingroup simix_comm_management
919  */
920 smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t *dst_buff_size,
921                                   int (*match_fun)(void *, void *, smx_action_t), void *data)
922 {
923   xbt_assert(rdv, "No rendez-vous point defined for irecv");
924
925   return simcall_BODY_comm_irecv(rdv, dst_buff, dst_buff_size, 
926                                  match_fun, data);
927 }
928
929
930 /**
931  * \ingroup simix_comm_management
932  */
933 void simcall_comm_recv_bounded(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
934                          int (*match_fun)(void *, void *, smx_action_t), void *data, double timeout, double rate)
935 {
936   xbt_assert(isfinite(timeout), "timeout is not finite!");
937   xbt_assert(rdv, "No rendez-vous point defined for recv");
938
939   if (MC_is_active()) {
940     /* the model-checker wants two separate simcalls */
941     smx_action_t comm = simcall_comm_irecv_bounded(rdv, dst_buff, dst_buff_size,
942         match_fun, data, rate);
943     simcall_comm_wait(comm, timeout);
944   }
945   else {
946     simcall_BODY_comm_recv_bounded(rdv, dst_buff, dst_buff_size,
947                            match_fun, data, timeout, rate);
948   }
949 }
950 /**
951  * \ingroup simix_comm_management
952  */
953 smx_action_t simcall_comm_irecv_bounded(smx_rdv_t rdv, void *dst_buff, size_t *dst_buff_size,
954                                   int (*match_fun)(void *, void *, smx_action_t), void *data, double rate)
955 {
956   xbt_assert(rdv, "No rendez-vous point defined for irecv");
957
958   return simcall_BODY_comm_irecv_bounded(rdv, dst_buff, dst_buff_size,
959                                  match_fun, data, rate);
960 }
961
962
963 /**
964  * \ingroup simix_comm_management
965  */
966 smx_action_t simcall_comm_iprobe(smx_rdv_t rdv, int src, int tag,
967                                 int (*match_fun)(void *, void *, smx_action_t), void *data)
968 {
969   xbt_assert(rdv, "No rendez-vous point defined for iprobe");
970
971   return simcall_BODY_comm_iprobe(rdv, src, tag, match_fun, data);
972 }
973
974 void simcall_comm_destroy(smx_action_t comm)
975 {
976   xbt_assert(comm, "Invalid parameter");
977
978   /* FIXME remove this simcall type: comms are auto-destroyed now */
979
980   /*
981   smx_simcall_t simcall = simcall_mine();
982
983   simcall->call = SIMCALL_COMM_DESTROY;
984   simcall->comm_destroy.comm = comm;
985
986   SIMIX_simcall_push(simcall->issuer);
987   */
988 }
989
990 /**
991  * \ingroup simix_comm_management
992  */
993 void simcall_comm_cancel(smx_action_t comm)
994 {
995   simcall_BODY_comm_cancel(comm);
996 }
997
998 /**
999  * \ingroup simix_comm_management
1000  */
1001 unsigned int simcall_comm_waitany(xbt_dynar_t comms)
1002 {
1003   return simcall_BODY_comm_waitany(comms);
1004 }
1005
1006 /**
1007  * \ingroup simix_comm_management
1008  */
1009 int simcall_comm_testany(xbt_dynar_t comms)
1010 {
1011   if (xbt_dynar_is_empty(comms))
1012     return -1;
1013   return simcall_BODY_comm_testany(comms);
1014 }
1015
1016 /**
1017  * \ingroup simix_comm_management
1018  */
1019 void simcall_comm_wait(smx_action_t comm, double timeout)
1020 {
1021   xbt_assert(isfinite(timeout), "timeout is not finite!");
1022   simcall_BODY_comm_wait(comm, timeout);
1023 }
1024
1025 #ifdef HAVE_TRACING
1026 /**
1027  * \brief Set the category of an action.
1028  *
1029  * This functions changes the category only. It calls a surf function.
1030  * \param execution The execution action
1031  * \param category The tracing category
1032  */
1033 void simcall_set_category(smx_action_t action, const char *category)
1034 {
1035   if (category == NULL) {
1036     return;
1037   }
1038   simcall_BODY_set_category(action, category);
1039 }
1040 #endif
1041
1042 /**
1043  * \ingroup simix_comm_management
1044  *
1045  */
1046 int simcall_comm_test(smx_action_t comm)
1047 {
1048   return simcall_BODY_comm_test(comm);
1049 }
1050
1051 /**
1052  * \ingroup simix_comm_management
1053  *
1054  */
1055 double simcall_comm_get_remains(smx_action_t comm)
1056 {
1057   return simcall_BODY_comm_get_remains(comm);
1058 }
1059
1060 /**
1061  * \ingroup simix_comm_management
1062  *
1063  */
1064 e_smx_state_t simcall_comm_get_state(smx_action_t comm)
1065 {
1066   return simcall_BODY_comm_get_state(comm);
1067 }
1068
1069 /**
1070  * \ingroup simix_comm_management
1071  *
1072  */
1073 void *simcall_comm_get_src_data(smx_action_t comm)
1074 {
1075   return simcall_BODY_comm_get_src_data(comm);
1076 }
1077
1078 /**
1079  * \ingroup simix_comm_management
1080  *
1081  */
1082 void *simcall_comm_get_dst_data(smx_action_t comm)
1083 {
1084   return simcall_BODY_comm_get_dst_data(comm);
1085 }
1086
1087 /**
1088  * \ingroup simix_comm_management
1089  *
1090  */
1091 smx_process_t simcall_comm_get_src_proc(smx_action_t comm)
1092 {
1093   return simcall_BODY_comm_get_src_proc(comm);
1094 }
1095
1096 /**
1097  * \ingroup simix_comm_management
1098  *
1099  */
1100 smx_process_t simcall_comm_get_dst_proc(smx_action_t comm)
1101 {
1102   return simcall_BODY_comm_get_dst_proc(comm);  
1103 }
1104
1105 #ifdef HAVE_LATENCY_BOUND_TRACKING
1106 int simcall_comm_is_latency_bounded(smx_action_t comm)
1107 {
1108   return simcall_BODY_comm_is_latency_bounded(comm);
1109 }
1110 #endif
1111
1112 /**
1113  * \ingroup simix_synchro_management
1114  *
1115  */
1116 smx_mutex_t simcall_mutex_init(void)
1117 {
1118   if(!simix_global) {
1119     fprintf(stderr,"You must run MSG_init before using MSG\n"); // We can't use xbt_die since we may get there before the initialization
1120     xbt_abort();
1121   }
1122   return simcall_BODY_mutex_init();
1123 }
1124
1125 /**
1126  * \ingroup simix_synchro_management
1127  *
1128  */
1129 void simcall_mutex_destroy(smx_mutex_t mutex)
1130 {
1131   simcall_BODY_mutex_destroy(mutex);
1132 }
1133
1134 /**
1135  * \ingroup simix_synchro_management
1136  *
1137  */
1138 void simcall_mutex_lock(smx_mutex_t mutex)
1139 {
1140   simcall_BODY_mutex_lock(mutex);  
1141 }
1142
1143 /**
1144  * \ingroup simix_synchro_management
1145  *
1146  */
1147 int simcall_mutex_trylock(smx_mutex_t mutex)
1148 {
1149   return simcall_BODY_mutex_trylock(mutex);  
1150 }
1151
1152 /**
1153  * \ingroup simix_synchro_management
1154  *
1155  */
1156 void simcall_mutex_unlock(smx_mutex_t mutex)
1157 {
1158   simcall_BODY_mutex_unlock(mutex); 
1159 }
1160
1161 /**
1162  * \ingroup simix_synchro_management
1163  *
1164  */
1165 smx_cond_t simcall_cond_init(void)
1166 {
1167   return simcall_BODY_cond_init();
1168 }
1169
1170 /**
1171  * \ingroup simix_synchro_management
1172  *
1173  */
1174 void simcall_cond_destroy(smx_cond_t cond)
1175 {
1176   simcall_BODY_cond_destroy(cond);
1177 }
1178
1179 /**
1180  * \ingroup simix_synchro_management
1181  *
1182  */
1183 void simcall_cond_signal(smx_cond_t cond)
1184 {
1185   simcall_BODY_cond_signal(cond);
1186 }
1187
1188 /**
1189  * \ingroup simix_synchro_management
1190  *
1191  */
1192 void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
1193 {
1194   simcall_BODY_cond_wait(cond, mutex);
1195 }
1196
1197 /**
1198  * \ingroup simix_synchro_management
1199  *
1200  */
1201 void simcall_cond_wait_timeout(smx_cond_t cond,
1202                                  smx_mutex_t mutex,
1203                                  double timeout)
1204 {
1205   xbt_assert(isfinite(timeout), "timeout is not finite!");
1206   simcall_BODY_cond_wait_timeout(cond, mutex, timeout);
1207 }
1208
1209 /**
1210  * \ingroup simix_synchro_management
1211  *
1212  */
1213 void simcall_cond_broadcast(smx_cond_t cond)
1214 {
1215   simcall_BODY_cond_broadcast(cond);
1216 }
1217
1218 /**
1219  * \ingroup simix_synchro_management
1220  *
1221  */
1222 smx_sem_t simcall_sem_init(int capacity)
1223 {
1224   return simcall_BODY_sem_init(capacity);  
1225 }
1226
1227 /**
1228  * \ingroup simix_synchro_management
1229  *
1230  */
1231 void simcall_sem_destroy(smx_sem_t sem)
1232 {
1233   simcall_sem_destroy(sem);
1234 }
1235
1236 /**
1237  * \ingroup simix_synchro_management
1238  *
1239  */
1240 void simcall_sem_release(smx_sem_t sem)
1241 {
1242   simcall_BODY_sem_release(sem);  
1243 }
1244
1245 /**
1246  * \ingroup simix_synchro_management
1247  *
1248  */
1249 int simcall_sem_would_block(smx_sem_t sem)
1250 {
1251   return simcall_BODY_sem_would_block(sem);
1252 }
1253
1254 /**
1255  * \ingroup simix_synchro_management
1256  *
1257  */
1258 void simcall_sem_acquire(smx_sem_t sem)
1259 {
1260   simcall_BODY_sem_acquire(sem);
1261 }
1262
1263 /**
1264  * \ingroup simix_synchro_management
1265  *
1266  */
1267 void simcall_sem_acquire_timeout(smx_sem_t sem, double timeout)
1268 {
1269   xbt_assert(isfinite(timeout), "timeout is not finite!");
1270   simcall_BODY_sem_acquire_timeout(sem, timeout);
1271 }
1272
1273 /**
1274  * \ingroup simix_synchro_management
1275  *
1276  */
1277 int simcall_sem_get_capacity(smx_sem_t sem)
1278 {
1279   return simcall_BODY_sem_get_capacity(sem);
1280 }
1281
1282 /**
1283  * \ingroup simix_file_management
1284  *
1285  */
1286 double simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1287 {
1288   return simcall_BODY_file_read(ptr, size, nmemb, stream);
1289 }
1290
1291 /**
1292  * \ingroup simix_file_management
1293  *
1294  */
1295 size_t simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1296 {
1297   return simcall_BODY_file_write(ptr, size, nmemb, stream);
1298 }
1299
1300 /**
1301  * \ingroup simix_file_management
1302  * \brief
1303  */
1304 smx_file_t simcall_file_open(const char* mount, const char* path, const char* mode)
1305 {
1306   return simcall_BODY_file_open(mount, path, mode);
1307 }
1308
1309 /**
1310  * \ingroup simix_file_management
1311  *
1312  */
1313 int simcall_file_close(smx_file_t fp)
1314 {
1315   return simcall_BODY_file_close(fp);  
1316 }
1317
1318 /**
1319  * \ingroup simix_file_management
1320  *
1321  */
1322 int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
1323 {
1324   return simcall_BODY_file_stat(fd, buf);
1325 }
1326
1327 /**
1328  * \ingroup simix_file_management
1329  *
1330  */
1331 int simcall_file_unlink(smx_file_t fd)
1332 {
1333   return simcall_BODY_file_unlink(fd);
1334 }
1335
1336 /**
1337  * \ingroup simix_file_management
1338  *
1339  */
1340 xbt_dict_t simcall_file_ls(const char* mount, const char* path)
1341 {
1342   return simcall_BODY_file_ls(mount, path);
1343 }
1344
1345 #ifdef HAVE_MC
1346
1347 void *simcall_mc_snapshot(void)
1348 {
1349   return simcall_BODY_mc_snapshot();
1350 }
1351
1352 int simcall_mc_compare_snapshots(void *s1, void *s2){ 
1353   return simcall_BODY_mc_compare_snapshots(s1, s2);
1354 }
1355
1356 int simcall_mc_random(void)
1357 {
1358   return simcall_BODY_mc_random();
1359 }
1360
1361
1362 #endif /* HAVE_MC */
1363
1364 /* ****************************************************************************************** */
1365 /* TUTORIAL: New API                                                                          */
1366 /* All functions for simcall                                                                  */
1367 /* ****************************************************************************************** */
1368 int simcall_new_api_fct(const char* param1, double param2){
1369   smx_simcall_t simcall = SIMIX_simcall_mine();
1370   simcall->call = SIMCALL_NEW_API_INIT;
1371   simcall->new_api.param1 = param1;
1372   simcall->new_api.param2 = param2;
1373
1374   SIMIX_simcall_push(simcall->issuer);
1375   return simcall->new_api.result;
1376 }
1377
1378 /* ************************************************************************** */
1379
1380 /** @brief returns a printable string representing a simcall */
1381 const char *SIMIX_simcall_name(e_smx_simcall_t kind) {
1382   return simcall_names[kind];
1383 }