Logo AND Algorithmique Numérique Distribuée

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