Logo AND Algorithmique Numérique Distribuée

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