Logo AND Algorithmique Numérique Distribuée

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