Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
4fd6d54654943ca71a02f96aa1177290df7d3282
[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 <cmath>         /* std::isfinite() */
15
16 #include <functional>
17
18 #include <xbt/functional.hpp>
19
20 #include <simgrid/simix/blocking_simcall.hpp>
21
22 #include "src/mc/mc_replay.h"
23 #include "smx_private.h"
24 #include "src/mc/mc_forward.hpp"
25 #include "xbt/ex.h"
26 #include "mc/mc.h"
27 #include "src/simix/smx_host_private.h"
28 #include "src/kernel/activity/SynchroComm.hpp"
29 #include "src/surf/virtual_machine.hpp"
30
31
32 #include <simgrid/simix.hpp>
33
34 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
35
36 #include "popping_bodies.cpp"
37
38 void simcall_call(smx_actor_t process)
39 {
40   if (process != simix_global->maestro_process) {
41     XBT_DEBUG("Yield process '%s' on simcall %s (%d)", process->name.c_str(),
42               SIMIX_simcall_name(process->simcall.call), (int)process->simcall.call);
43     SIMIX_process_yield(process);
44   } else {
45     SIMIX_simcall_handle(&process->simcall, 0);
46   }
47 }
48
49 // ***** AS simcalls
50
51 /**
52  * \ingroup simix_host_management
53  * \brief Returns a dict of the properties assigned to a router or AS.
54  *
55  * \param name The name of the router or AS
56  * \return The properties
57  */
58 xbt_dict_t simcall_asr_get_properties(const char *name)
59 {
60   return simcall_BODY_asr_get_properties(name);
61 }
62
63 /**
64  * \ingroup simix_process_management
65  * \brief Creates a synchro that executes some computation of an host.
66  *
67  * This function creates a SURF action and allocates the data necessary
68  * to create the SIMIX synchro. It can raise a host_error exception if the host crashed.
69  *
70  * \param name Name of the execution synchro to create
71  * \param flops_amount amount Computation amount (in flops)
72  * \param priority computation priority
73  * \param bound
74  * \return A new SIMIX execution synchronization
75  */
76 smx_activity_t simcall_execution_start(const char *name,
77                                     double flops_amount,
78                                     double priority, double bound)
79 {
80   /* checking for infinite values */
81   xbt_assert(std::isfinite(flops_amount), "flops_amount is not finite!");
82   xbt_assert(std::isfinite(priority), "priority is not finite!");
83
84   return simcall_BODY_execution_start(name, flops_amount, priority, bound);
85 }
86
87 /**
88  * \ingroup simix_process_management
89  * \brief Creates a synchro that may involve parallel computation on
90  * several hosts and communication between them.
91  *
92  * \param name Name of the execution synchro to create
93  * \param host_nb Number of hosts where the synchro will be executed
94  * \param host_list Array (of size host_nb) of hosts where the synchro will be executed
95  * \param flops_amount Array (of size host_nb) of computation amount of hosts (in bytes)
96  * \param bytes_amount Array (of size host_nb * host_nb) representing the communication
97  * amount between each pair of hosts
98  * \param amount the SURF action amount
99  * \param rate the SURF action rate
100  * \return A new SIMIX execution synchronization
101  */
102 smx_activity_t simcall_execution_parallel_start(const char *name,
103                                          int host_nb,
104                                          sg_host_t *host_list,
105                                          double *flops_amount,
106                                          double *bytes_amount,
107                                          double amount,
108                                          double rate)
109 {
110   int i,j;
111   /* checking for infinite values */
112   for (i = 0 ; i < host_nb ; ++i) {
113     xbt_assert(std::isfinite(flops_amount[i]), "flops_amount[%d] is not finite!", i);
114     if (bytes_amount != nullptr) {
115       for (j = 0 ; j < host_nb ; ++j) {
116         xbt_assert(std::isfinite(bytes_amount[i + host_nb * j]),
117                    "bytes_amount[%d+%d*%d] is not finite!", i, host_nb, j);
118       }
119     }
120   }
121
122   xbt_assert(std::isfinite(amount), "amount is not finite!");
123   xbt_assert(std::isfinite(rate), "rate is not finite!");
124
125   return simcall_BODY_execution_parallel_start(name, host_nb, host_list,
126                                             flops_amount,
127                                             bytes_amount,
128                                             amount, rate);
129
130 }
131
132 /**
133  * \ingroup simix_process_management
134  * \brief Cancels an execution synchro.
135  *
136  * This functions stops the execution. It calls a surf function.
137  * \param execution The execution synchro to cancel
138  */
139 void simcall_execution_cancel(smx_activity_t execution)
140 {
141   simcall_BODY_execution_cancel(execution);
142 }
143
144 /**
145  * \ingroup simix_process_management
146  * \brief Changes the priority of an execution synchro.
147  *
148  * This functions changes the priority only. It calls a surf function.
149  * \param execution The execution synchro
150  * \param priority The new priority
151  */
152 void simcall_execution_set_priority(smx_activity_t execution, double priority)
153 {
154   /* checking for infinite values */
155   xbt_assert(std::isfinite(priority), "priority is not finite!");
156
157   simcall_BODY_execution_set_priority(execution, priority);
158 }
159
160 /**
161  * \ingroup simix_process_management
162  * \brief Changes the capping (the maximum CPU utilization) of an execution synchro.
163  *
164  * This functions changes the capping only. It calls a surf function.
165  * \param execution The execution synchro
166  * \param bound The new bound
167  */
168 void simcall_execution_set_bound(smx_activity_t execution, double bound)
169 {
170   simcall_BODY_execution_set_bound(execution, bound);
171 }
172
173 /**
174  * \ingroup simix_host_management
175  * \brief Waits for the completion of an execution synchro and destroy it.
176  *
177  * \param execution The execution synchro
178  */
179 e_smx_state_t simcall_execution_wait(smx_activity_t execution)
180 {
181   return (e_smx_state_t) simcall_BODY_execution_wait(execution);
182 }
183
184
185 /**
186  * \ingroup simix_vm_management
187  * \brief Create a VM on the given physical host.
188  *
189  * \param name VM name
190  * \param host Physical host
191  *
192  * \return The host object of the VM
193  */
194 sg_host_t simcall_vm_create(const char *name, sg_host_t phys_host)
195 {
196   return simgrid::simix::kernelImmediate([&name, &phys_host] {
197     sg_host_t host = surf_vm_model->createVM(name, phys_host);
198     SIMIX_host_create(host);
199
200     return host;
201   });
202 }
203
204 /**
205  * \ingroup simix_vm_management
206  * \brief Start the given VM to the given physical host
207  *
208  * \param vm VM
209  */
210 void simcall_vm_start(sg_host_t vm)
211 {
212   simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_start, vm));
213 }
214
215 /**
216  * \ingroup simix_vm_management
217  * \brief Get the state of the given VM
218  *
219  * \param vm VM
220  * \return The state of the VM
221  */
222 int simcall_vm_get_state(sg_host_t vm)
223 {
224   return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_get_state, vm));
225 }
226
227 /**
228  * \ingroup simix_vm_management
229  * \brief Get the name of the physical host on which the given VM runs.
230  *
231  * \param vm VM
232  * \return The name of the physical host
233  */
234 void *simcall_vm_get_pm(sg_host_t vm)
235 {
236   return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_get_pm, vm));
237 }
238
239 void simcall_vm_set_bound(sg_host_t vm, double bound)
240 {
241   simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_set_bound, vm, bound));
242 }
243
244 /**
245  * \ingroup simix_vm_management
246  * \brief Migrate the given VM to the given physical host
247  *
248  * \param vm VM
249  * \param host Destination physical host
250  */
251 void simcall_vm_migrate(sg_host_t vm, sg_host_t host)
252 {
253   simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_migrate, vm, host));
254 }
255
256 /**
257  * \ingroup simix_vm_management
258  * \brief Suspend the given VM
259  *
260  * \param vm VM
261  */
262 void simcall_vm_suspend(sg_host_t vm)
263 {
264   simcall_BODY_vm_suspend(vm);
265 }
266
267 /**
268  * \ingroup simix_vm_management
269  * \brief Resume the given VM
270  *
271  * \param vm VM
272  */
273 void simcall_vm_resume(sg_host_t vm)
274 {
275   simcall_BODY_vm_resume(vm);
276 }
277
278 /**
279  * \ingroup simix_vm_management
280  * \brief Save the given VM
281  *
282  * \param vm VM
283  */
284 void simcall_vm_save(sg_host_t vm)
285 {
286   simcall_BODY_vm_save(vm);
287 }
288
289 /**
290  * \ingroup simix_vm_management
291  * \brief Restore the given VM
292  *
293  * \param vm VM
294  */
295 void simcall_vm_restore(sg_host_t vm)
296 {
297   simcall_BODY_vm_restore(vm);
298 }
299
300 /**
301  * \ingroup simix_vm_management
302  * \brief Shutdown the given VM
303  *
304  * \param vm VM
305  */
306 void simcall_vm_shutdown(sg_host_t vm)
307 {
308   simcall_BODY_vm_shutdown(vm);
309 }
310
311 /**
312  * \ingroup simix_vm_management
313  * \brief Destroy the given VM
314  *
315  * \param vm VM
316  */
317 void simcall_vm_destroy(sg_host_t vm)
318 {
319   simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_destroy, vm));
320 }
321
322 /**
323  * \ingroup simix_vm_management
324  * \brief Encompassing simcall to prevent the removal of the src or the dst node at the end of a VM migration
325  *  The simcall actually invokes the following calls: 
326  *     simcall_vm_migrate(vm, dst_pm); 
327  *     simcall_vm_resume(vm);
328  *
329  * It is called at the end of the migration_rx_fun function from msg/msg_vm.c
330  *
331  * \param vm VM to migrate
332  * \param src_pm  Source physical host
333  * \param dst_pmt Destination physical host
334  */
335 void simcall_vm_migratefrom_resumeto(sg_host_t vm, sg_host_t src_pm, sg_host_t dst_pm)
336 {
337   simgrid::simix::kernelImmediate(std::bind(
338     SIMIX_vm_migratefrom_resumeto, vm, src_pm, dst_pm));
339 }
340
341 /**
342  * \ingroup simix_process_management
343  * \brief Kills a SIMIX process.
344  *
345  * This function simply kills a  process.
346  *
347  * \param process poor victim
348  */
349 void simcall_process_kill(smx_actor_t process)
350 {
351   simcall_BODY_process_kill(process);
352 }
353
354 /**
355  * \ingroup simix_process_management
356  * \brief Kills all SIMIX processes.
357  */
358 void simcall_process_killall(int reset_pid)
359 {
360   simcall_BODY_process_killall(reset_pid);
361 }
362
363 /**
364  * \ingroup simix_process_management
365  * \brief Cleans up a SIMIX process.
366  * \param process poor victim (must have already been killed)
367  */
368 void simcall_process_cleanup(smx_actor_t process)
369 {
370   simcall_BODY_process_cleanup(process);
371 }
372
373 /**
374  * \ingroup simix_process_management
375  * \brief Migrates an agent to another location.
376  *
377  * This function changes the value of the host on which \a process is running.
378  *
379  * \param process the process to migrate
380  * \param dest name of the new host
381  */
382 void simcall_process_set_host(smx_actor_t process, sg_host_t dest)
383 {
384   simcall_BODY_process_set_host(process, dest);
385 }
386
387 void simcall_process_join(smx_actor_t process, double timeout)
388 {
389   simcall_BODY_process_join(process, timeout);
390 }
391
392 /**
393  * \ingroup simix_process_management
394  * \brief Suspends a process.
395  *
396  * This function suspends the process by suspending the synchro
397  * it was waiting for completion.
398  *
399  * \param process a SIMIX process
400  */
401 void simcall_process_suspend(smx_actor_t process)
402 {
403   xbt_assert(process, "Invalid parameters");
404
405   simcall_BODY_process_suspend(process);
406 }
407
408 /**
409  * \ingroup simix_process_management
410  * \brief Resumes a suspended process.
411  *
412  * This function resumes a suspended process by resuming the synchro
413  * it was waiting for completion.
414  *
415  * \param process a SIMIX process
416  */
417 void simcall_process_resume(smx_actor_t process)
418 {
419   simcall_BODY_process_resume(process);
420 }
421
422 /**
423  * \ingroup simix_process_management
424  * \brief Returns the amount of SIMIX processes in the system
425  *
426  * Maestro internal process is not counted, only user code processes are
427  */
428 int simcall_process_count()
429 {
430   return simgrid::simix::kernelImmediate(SIMIX_process_count);
431 }
432
433 /**
434  * \ingroup simix_process_management
435  * \brief Return the user data of a #smx_actor_t.
436  * \param process a SIMIX process
437  * \return the user data of this process
438  */
439 void* simcall_process_get_data(smx_actor_t process)
440 {
441   return SIMIX_process_get_data(process);
442 }
443
444 /**
445  * \ingroup simix_process_management
446  * \brief Set the user data of a #smx_actor_t.
447  *
448  * This functions sets the user data associated to \a process.
449  * \param process SIMIX process
450  * \param data User data
451  */
452 void simcall_process_set_data(smx_actor_t process, void *data)
453 {
454   simgrid::simix::kernelImmediate(std::bind(SIMIX_process_set_data, process, data));
455 }
456
457 /**
458  * \ingroup simix_process_management
459  * \brief Set the kill time of a process.
460  */
461 void simcall_process_set_kill_time(smx_actor_t process, double kill_time)
462 {
463
464   if (kill_time <= SIMIX_get_clock() || simix_global->kill_process_function == nullptr)
465     return;
466   XBT_DEBUG("Set kill time %f for process %s(%s)",
467     kill_time, process->name.c_str(), sg_host_get_name(process->host));
468   process->kill_timer = SIMIX_timer_set(kill_time, [=] {
469     simix_global->kill_process_function(process);
470     process->kill_timer=nullptr;
471   });
472 }
473 /**
474  * \ingroup simix_process_management
475  * \brief Get the kill time of a process (or 0 if unset).
476  */
477 double simcall_process_get_kill_time(smx_actor_t process) {
478   return SIMIX_timer_get_date(process->kill_timer);
479 }
480
481 /**
482  * \ingroup simix_process_management
483  * \brief Returns true if the process is suspended .
484  *
485  * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
486  * \param process SIMIX process
487  * \return 1, if the process is suspended, else 0.
488  */
489 int simcall_process_is_suspended(smx_actor_t process)
490 {
491   return simcall_BODY_process_is_suspended(process);
492 }
493
494 /**
495  * \ingroup simix_process_management
496  * \brief Return the properties
497  *
498  * This functions returns the properties associated with this process
499  */
500 xbt_dict_t simcall_process_get_properties(smx_actor_t process)
501 {
502   return SIMIX_process_get_properties(process);
503 }
504 /**
505  * \ingroup simix_process_management
506  * \brief Add an on_exit function
507  * Add an on_exit function which will be executed when the process exits/is killed.
508  */
509 XBT_PUBLIC(void) simcall_process_on_exit(smx_actor_t process, int_f_pvoid_pvoid_t fun, void *data)
510 {
511   simcall_BODY_process_on_exit(process, fun, data);
512 }
513 /**
514  * \ingroup simix_process_management
515  * \brief Sets the process to be auto-restarted or not by SIMIX when its host comes back up.
516  * Will restart the process when the host comes back up if auto_restart is set to 1.
517  */
518
519 XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_actor_t process, int auto_restart)
520 {
521   simcall_BODY_process_auto_restart_set(process, auto_restart);
522 }
523
524 /**
525  * \ingroup simix_process_management
526  * \brief Restarts the process, killing it and starting it again from scratch.
527  */
528 XBT_PUBLIC(smx_actor_t) simcall_process_restart(smx_actor_t process)
529 {
530   return (smx_actor_t) simcall_BODY_process_restart(process);
531 }
532 /**
533  * \ingroup simix_process_management
534  * \brief Creates a new sleep SIMIX synchro.
535  *
536  * This function creates a SURF action and allocates the data necessary
537  * to create the SIMIX synchro. It can raise a host_error exception if the
538  * host crashed. The default SIMIX name of the synchro is "sleep".
539  *
540  *   \param duration Time duration of the sleep.
541  *   \return A result telling whether the sleep was successful
542  */
543 e_smx_state_t simcall_process_sleep(double duration)
544 {
545   /* checking for infinite values */
546   xbt_assert(std::isfinite(duration), "duration is not finite!");
547   return (e_smx_state_t) simcall_BODY_process_sleep(duration);
548 }
549
550 /**
551  *  \ingroup simix_mbox_management
552  *  \brief Creates a new rendez-vous point
553  *  \param name The name of the rendez-vous point
554  *  \return The created rendez-vous point
555  */
556 smx_mailbox_t simcall_mbox_create(const char *name)
557 {
558   return simcall_BODY_mbox_create(name);
559 }
560
561 void simcall_mbox_set_receiver(smx_mailbox_t mbox, smx_actor_t process)
562 {
563   simcall_BODY_mbox_set_receiver(mbox, process);
564 }
565
566 /**
567  * \ingroup simix_comm_management
568  */
569 void simcall_comm_send(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate,
570                          void *src_buff, size_t src_buff_size,
571                          int (*match_fun)(void *, void *, smx_activity_t),
572                          void (*copy_data_fun)(smx_activity_t, void*, size_t), void *data,
573                          double timeout)
574 {
575   /* checking for infinite values */
576   xbt_assert(std::isfinite(task_size), "task_size is not finite!");
577   xbt_assert(std::isfinite(rate), "rate is not finite!");
578   xbt_assert(std::isfinite(timeout), "timeout is not finite!");
579
580   xbt_assert(mbox, "No rendez-vous point defined for send");
581
582   if (MC_is_active() || MC_record_replay_is_active()) {
583     /* the model-checker wants two separate simcalls */
584     smx_activity_t comm = nullptr; /* MC needs the comm to be set to nullptr during the simcall */
585     comm = simcall_comm_isend(sender, mbox, task_size, rate,
586         src_buff, src_buff_size, match_fun, nullptr, copy_data_fun, data, 0);
587     simcall_comm_wait(comm, timeout);
588     comm = nullptr;
589   }
590   else {
591     simcall_BODY_comm_send(sender, mbox, task_size, rate, src_buff, src_buff_size,
592                          match_fun, copy_data_fun, data, timeout);
593   }
594 }
595
596 /**
597  * \ingroup simix_comm_management
598  */
599 smx_activity_t simcall_comm_isend(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate,
600                               void *src_buff, size_t src_buff_size,
601                               int (*match_fun)(void *, void *, smx_activity_t),
602                               void (*clean_fun)(void *),
603                               void (*copy_data_fun)(smx_activity_t, void*, size_t),
604                               void *data,
605                               int detached)
606 {
607   /* checking for infinite values */
608   xbt_assert(std::isfinite(task_size), "task_size is not finite!");
609   xbt_assert(std::isfinite(rate), "rate is not finite!");
610
611   xbt_assert(mbox, "No rendez-vous point defined for isend");
612
613   return simcall_BODY_comm_isend(sender, mbox, task_size, rate, src_buff,
614                                  src_buff_size, match_fun,
615                                  clean_fun, copy_data_fun, data, detached);
616 }
617
618 /**
619  * \ingroup simix_comm_management
620  */
621 void simcall_comm_recv(smx_actor_t receiver, smx_mailbox_t mbox, void *dst_buff, size_t * dst_buff_size,
622                        int (*match_fun)(void *, void *, smx_activity_t),
623                        void (*copy_data_fun)(smx_activity_t, void*, size_t),
624                        void *data, double timeout, double rate)
625 {
626   xbt_assert(std::isfinite(timeout), "timeout is not finite!");
627   xbt_assert(mbox, "No rendez-vous point defined for recv");
628
629   if (MC_is_active() || MC_record_replay_is_active()) {
630     /* the model-checker wants two separate simcalls */
631     smx_activity_t comm = nullptr; /* MC needs the comm to be set to nullptr during the simcall */
632     comm = simcall_comm_irecv(receiver, mbox, dst_buff, dst_buff_size,
633                               match_fun, copy_data_fun, data, rate);
634     simcall_comm_wait(comm, timeout);
635     comm = nullptr;
636   }
637   else {
638     simcall_BODY_comm_recv(receiver, mbox, dst_buff, dst_buff_size,
639                            match_fun, copy_data_fun, data, timeout, rate);
640   }
641 }
642 /**
643  * \ingroup simix_comm_management
644  */
645 smx_activity_t simcall_comm_irecv(smx_actor_t receiver, smx_mailbox_t mbox, void *dst_buff, size_t *dst_buff_size,
646                                 int (*match_fun)(void *, void *, smx_activity_t),
647                                 void (*copy_data_fun)(smx_activity_t, void*, size_t),
648                                 void *data, double rate)
649 {
650   xbt_assert(mbox, "No rendez-vous point defined for irecv");
651
652   return simcall_BODY_comm_irecv(receiver, mbox, dst_buff, dst_buff_size,
653                                  match_fun, copy_data_fun, data, rate);
654 }
655
656 /**
657  * \ingroup simix_comm_management
658  */
659 smx_activity_t simcall_comm_iprobe(smx_mailbox_t mbox, int type, int src, int tag,
660                                 int (*match_fun)(void *, void *, smx_activity_t), void *data)
661 {
662   xbt_assert(mbox, "No rendez-vous point defined for iprobe");
663
664   return simcall_BODY_comm_iprobe(mbox, type, src, tag, match_fun, data);
665 }
666
667 /**
668  * \ingroup simix_comm_management
669  */
670 void simcall_comm_cancel(smx_activity_t synchro)
671 {
672   simgrid::simix::kernelImmediate([synchro]{
673     simgrid::kernel::activity::Comm *comm = static_cast<simgrid::kernel::activity::Comm*>(synchro);
674     comm->cancel();
675   });
676 }
677
678 /**
679  * \ingroup simix_comm_management
680  */
681 unsigned int simcall_comm_waitany(xbt_dynar_t comms, double timeout)
682 {
683   return simcall_BODY_comm_waitany(comms, timeout);
684 }
685
686 /**
687  * \ingroup simix_comm_management
688  */
689 int simcall_comm_testany(smx_activity_t* comms, size_t count)
690 {
691   if (count == 0)
692     return -1;
693   return simcall_BODY_comm_testany(comms, count);
694 }
695
696 /**
697  * \ingroup simix_comm_management
698  */
699 void simcall_comm_wait(smx_activity_t comm, double timeout)
700 {
701   xbt_assert(std::isfinite(timeout), "timeout is not finite!");
702   simcall_BODY_comm_wait(comm, timeout);
703 }
704
705 /**
706  * \brief Set the category of an synchro.
707  *
708  * This functions changes the category only. It calls a surf function.
709  * \param execution The execution synchro
710  * \param category The tracing category
711  */
712 void simcall_set_category(smx_activity_t synchro, const char *category)
713 {
714   if (category == nullptr) {
715     return;
716   }
717   simcall_BODY_set_category(synchro, category);
718 }
719
720 /**
721  * \ingroup simix_comm_management
722  *
723  */
724 int simcall_comm_test(smx_activity_t comm)
725 {
726   return simcall_BODY_comm_test(comm);
727 }
728
729 /**
730  * \ingroup simix_synchro_management
731  *
732  */
733 smx_mutex_t simcall_mutex_init()
734 {
735   if(!simix_global) {
736     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
737     xbt_abort();
738   }
739   return simcall_BODY_mutex_init();
740 }
741
742 /**
743  * \ingroup simix_synchro_management
744  *
745  */
746 void simcall_mutex_lock(smx_mutex_t mutex)
747 {
748   simcall_BODY_mutex_lock(mutex);
749 }
750
751 /**
752  * \ingroup simix_synchro_management
753  *
754  */
755 int simcall_mutex_trylock(smx_mutex_t mutex)
756 {
757   return simcall_BODY_mutex_trylock(mutex);
758 }
759
760 /**
761  * \ingroup simix_synchro_management
762  *
763  */
764 void simcall_mutex_unlock(smx_mutex_t mutex)
765 {
766   simcall_BODY_mutex_unlock(mutex);
767 }
768
769 /**
770  * \ingroup simix_synchro_management
771  *
772  */
773 smx_cond_t simcall_cond_init()
774 {
775   return simcall_BODY_cond_init();
776 }
777
778 /**
779  * \ingroup simix_synchro_management
780  *
781  */
782 void simcall_cond_signal(smx_cond_t cond)
783 {
784   simcall_BODY_cond_signal(cond);
785 }
786
787 /**
788  * \ingroup simix_synchro_management
789  *
790  */
791 void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
792 {
793   simcall_BODY_cond_wait(cond, mutex);
794 }
795
796 /**
797  * \ingroup simix_synchro_management
798  *
799  */
800 void simcall_cond_wait_timeout(smx_cond_t cond,
801                                  smx_mutex_t mutex,
802                                  double timeout)
803 {
804   xbt_assert(std::isfinite(timeout), "timeout is not finite!");
805   simcall_BODY_cond_wait_timeout(cond, mutex, timeout);
806 }
807
808 /**
809  * \ingroup simix_synchro_management
810  *
811  */
812 void simcall_cond_broadcast(smx_cond_t cond)
813 {
814   simcall_BODY_cond_broadcast(cond);
815 }
816
817 /**
818  * \ingroup simix_synchro_management
819  *
820  */
821 smx_sem_t simcall_sem_init(int capacity)
822 {
823   return simcall_BODY_sem_init(capacity);
824 }
825
826 /**
827  * \ingroup simix_synchro_management
828  *
829  */
830 void simcall_sem_release(smx_sem_t sem)
831 {
832   simcall_BODY_sem_release(sem);
833 }
834
835 /**
836  * \ingroup simix_synchro_management
837  *
838  */
839 int simcall_sem_would_block(smx_sem_t sem)
840 {
841   return simcall_BODY_sem_would_block(sem);
842 }
843
844 /**
845  * \ingroup simix_synchro_management
846  *
847  */
848 void simcall_sem_acquire(smx_sem_t sem)
849 {
850   simcall_BODY_sem_acquire(sem);
851 }
852
853 /**
854  * \ingroup simix_synchro_management
855  *
856  */
857 void simcall_sem_acquire_timeout(smx_sem_t sem, double timeout)
858 {
859   xbt_assert(std::isfinite(timeout), "timeout is not finite!");
860   simcall_BODY_sem_acquire_timeout(sem, timeout);
861 }
862
863 /**
864  * \ingroup simix_synchro_management
865  *
866  */
867 int simcall_sem_get_capacity(smx_sem_t sem)
868 {
869   return simcall_BODY_sem_get_capacity(sem);
870 }
871
872 /**
873  * \ingroup simix_file_management
874  *
875  */
876 sg_size_t simcall_file_read(smx_file_t fd, sg_size_t size, sg_host_t host)
877 {
878   return simcall_BODY_file_read(fd, size, host);
879 }
880
881 /**
882  * \ingroup simix_file_management
883  *
884  */
885 sg_size_t simcall_file_write(smx_file_t fd, sg_size_t size, sg_host_t host)
886 {
887   return simcall_BODY_file_write(fd, size, host);
888 }
889
890 /**
891  * \ingroup simix_file_management
892  * \brief
893  */
894 smx_file_t simcall_file_open(const char* fullpath, sg_host_t host)
895 {
896   return simcall_BODY_file_open(fullpath, host);
897 }
898
899 /**
900  * \ingroup simix_file_management
901  *
902  */
903 int simcall_file_close(smx_file_t fd, sg_host_t host)
904 {
905   return simcall_BODY_file_close(fd, host);
906 }
907
908 /**
909  * \ingroup simix_file_management
910  *
911  */
912 int simcall_file_unlink(smx_file_t fd, sg_host_t host)
913 {
914   return simcall_BODY_file_unlink(fd, host);
915 }
916
917 /**
918  * \ingroup simix_file_management
919  *
920  */
921 sg_size_t simcall_file_get_size(smx_file_t fd){
922   return simcall_BODY_file_get_size(fd);
923 }
924
925 /**
926  * \ingroup simix_file_management
927  *
928  */
929 sg_size_t simcall_file_tell(smx_file_t fd){
930   return simcall_BODY_file_tell(fd);
931 }
932
933 /**
934  * \ingroup simix_file_management
935  *
936  */
937 xbt_dynar_t simcall_file_get_info(smx_file_t fd)
938 {
939   return simcall_BODY_file_get_info(fd);
940 }
941
942 /**
943  * \ingroup simix_file_management
944  *
945  */
946 int simcall_file_seek(smx_file_t fd, sg_offset_t offset, int origin){
947   return simcall_BODY_file_seek(fd, offset, origin);
948 }
949
950 /**
951  * \ingroup simix_file_management
952  * \brief Move a file to another location on the *same mount point*.
953  *
954  */
955 int simcall_file_move(smx_file_t fd, const char* fullpath)
956 {
957   return simcall_BODY_file_move(fd, fullpath);
958 }
959
960 /**
961  * \ingroup simix_storage_management
962  * \brief Returns the free space size on a given storage element.
963  * \param storage a storage
964  * \return Return the free space size on a given storage element (as sg_size_t)
965  */
966 sg_size_t simcall_storage_get_free_size (smx_storage_t storage){
967   return simcall_BODY_storage_get_free_size(storage);
968 }
969
970 /**
971  * \ingroup simix_storage_management
972  * \brief Returns the used space size on a given storage element.
973  * \param storage a storage
974  * \return Return the used space size on a given storage element (as sg_size_t)
975  */
976 sg_size_t simcall_storage_get_used_size (smx_storage_t storage){
977   return simcall_BODY_storage_get_used_size(storage);
978 }
979
980 /**
981  * \ingroup simix_storage_management
982  * \brief Returns a dict of the properties assigned to a storage element.
983  *
984  * \param storage A storage element
985  * \return The properties of this storage element
986  */
987 xbt_dict_t simcall_storage_get_properties(smx_storage_t storage)
988 {
989   return simcall_BODY_storage_get_properties(storage);
990 }
991
992 /**
993  * \ingroup simix_storage_management
994  * \brief Returns a dict containing the content of a storage element.
995  *
996  * \param storage A storage element
997  * \return The content of this storage element as a dict (full path file => size)
998  */
999 xbt_dict_t simcall_storage_get_content(smx_storage_t storage)
1000 {
1001   return simcall_BODY_storage_get_content(storage);
1002 }
1003
1004 void simcall_run_kernel(std::function<void()> const& code)
1005 {
1006   simcall_BODY_run_kernel(&code);
1007 }
1008
1009 void simcall_run_blocking(std::function<void()> const& code)
1010 {
1011   simcall_BODY_run_blocking(&code);
1012 }
1013
1014 int simcall_mc_random(int min, int max) {
1015   return simcall_BODY_mc_random(min, max);
1016 }
1017
1018 /* ************************************************************************** */
1019
1020 /** @brief returns a printable string representing a simcall */
1021 const char *SIMIX_simcall_name(e_smx_simcall_t kind) {
1022   return simcall_names[kind];
1023 }
1024
1025 namespace simgrid {
1026 namespace simix {
1027
1028 void unblock(smx_actor_t process)
1029 {
1030   xbt_assert(SIMIX_is_maestro());
1031   SIMIX_simcall_answer(&process->simcall);
1032 }
1033
1034 }
1035 }