Logo AND Algorithmique Numérique Distribuée

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