Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove unused function.
[simgrid.git] / src / simix / smx_user.c
1 /* smx_user.c - public interface to simix                                   */
2
3 /* Copyright (c) 2010, 2011. Da SimGrid team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "smx_private.h"
9 #include "mc/mc.h"
10 #include "xbt/ex.h"
11
12 #ifndef _SVID_SOURCE
13 #  define _SVID_SOURCE    /* strdup() */
14 #endif
15 #ifndef _ISOC99_SOURCE
16 #  define _ISOC99_SOURCE  /* isfinite() */
17 #endif
18 #ifndef _ISO_C99_SOURCE
19 #  define _ISO_C99_SOURCE /* isfinite() */
20 #endif
21 #include <math.h>         /* isfinite() */
22
23 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
24
25 static const char* simcall_names[] = {
26 #undef SIMCALL_ENUM_ELEMENT
27 #define SIMCALL_ENUM_ELEMENT(x) #x /* generate strings from the enumeration values */
28 SIMCALL_LIST
29 #undef SIMCALL_ENUM_ELEMENT
30 };
31
32 /**
33  * \ingroup simix_host_management
34  * \brief Returns a host given its name.
35  *
36  * \param name The name of the host to get
37  * \return The corresponding host
38  */
39 smx_host_t simcall_host_get_by_name(const char *name)
40 {
41   smx_simcall_t simcall = SIMIX_simcall_mine();
42
43   simcall->call = SIMCALL_HOST_GET_BY_NAME;
44   simcall->host_get_by_name.name = name;
45   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
46     simcall->host_get_by_name.result = NULL;
47   SIMIX_simcall_push(simcall->issuer);
48   return simcall->host_get_by_name.result;
49 }
50
51 /**
52  * \ingroup simix_host_management
53  * \brief Returns the name of a host.
54  *
55  * \param host A SIMIX host
56  * \return The name of this host
57  */
58 const char* simcall_host_get_name(smx_host_t host)
59 {
60   smx_simcall_t simcall = SIMIX_simcall_mine();
61
62   simcall->call = SIMCALL_HOST_GET_NAME;
63   simcall->host_get_name.host = host;
64   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
65     simcall->host_get_name.result = NULL;
66   SIMIX_simcall_push(simcall->issuer);
67   return simcall->host_get_name.result;
68 }
69
70 /**
71  * \ingroup simix_host_management
72  * \brief Returns a dict of the properties assigned to a host.
73  *
74  * \param host A host
75  * \return The properties of this host
76  */
77 xbt_dict_t simcall_host_get_properties(smx_host_t host)
78 {
79   smx_simcall_t simcall = SIMIX_simcall_mine();
80
81   simcall->call = SIMCALL_HOST_GET_PROPERTIES;
82   simcall->host_get_properties.host = host;
83   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
84     simcall->host_get_properties.result = NULL;
85   SIMIX_simcall_push(simcall->issuer);
86   return simcall->host_get_properties.result;
87 }
88
89 /**
90  * \ingroup simix_host_management
91  * \brief Returns a dict of the properties assigned to a router or AS.
92  *
93  * \param asr name of the router or AS
94  * \return The properties
95  */
96 xbt_dict_t simcall_asr_get_properties(const char *name)
97 {
98   smx_simcall_t simcall = SIMIX_simcall_mine();
99
100   simcall->call = SIMCALL_ASR_GET_PROPERTIES;
101   simcall->asr_get_properties.name = name;
102   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
103     simcall->asr_get_properties.result = NULL;
104   SIMIX_simcall_push(simcall->issuer);
105   return simcall->asr_get_properties.result;
106 }
107
108
109 /**
110  * \ingroup simix_host_management
111  * \brief Returns the speed of the processor.
112  *
113  * The speed returned does not take into account the current load on the machine.
114  * \param host A SIMIX host
115  * \return The speed of this host (in Mflop/s)
116  */
117 double simcall_host_get_speed(smx_host_t host)
118 {
119   smx_simcall_t simcall = SIMIX_simcall_mine();
120
121   simcall->call = SIMCALL_HOST_GET_SPEED;
122   simcall->host_get_speed.host = host;
123   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
124     simcall->host_get_speed.result = 0.0;
125   SIMIX_simcall_push(simcall->issuer);
126   return simcall->host_get_speed.result;
127 }
128
129 /**
130  * \ingroup simix_host_management
131  * \brief Returns the available speed of the processor.
132  *
133  * \return Speed currently available (in Mflop/s)
134  */
135 double simcall_host_get_available_speed(smx_host_t host)
136 {
137   smx_simcall_t simcall = SIMIX_simcall_mine();
138
139   simcall->call = SIMCALL_HOST_GET_AVAILABLE_SPEED;
140   simcall->host_get_available_speed.host = host;
141   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
142     simcall->host_get_available_speed.result = 0.0;
143   SIMIX_simcall_push(simcall->issuer);
144   return simcall->host_get_available_speed.result;
145 }
146
147 /**
148  * \ingroup simix_host_management
149  * \brief Returns the state of a host.
150  *
151  * Two states are possible: 1 if the host is active or 0 if it has crashed.
152  * \param host A SIMIX host
153  * \return 1 if the host is available, 0 otherwise
154  */
155 int simcall_host_get_state(smx_host_t host)
156 {
157   smx_simcall_t simcall = SIMIX_simcall_mine();
158
159   simcall->call = SIMCALL_HOST_GET_STATE;
160   simcall->host_get_state.host = host;
161   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
162     simcall->host_get_state.result = -1;
163   SIMIX_simcall_push(simcall->issuer);
164   return simcall->host_get_state.result;
165 }
166
167 /**
168  * \ingroup simix_host_management
169  * \brief Returns the user data associated to a host.
170  *
171  * \param host SIMIX host
172  * \return the user data of this host
173  */
174 void* simcall_host_get_data(smx_host_t host)
175 {
176   smx_simcall_t simcall = SIMIX_simcall_mine();
177
178   simcall->call = SIMCALL_HOST_GET_DATA;
179   simcall->host_get_data.host = host;
180   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
181     simcall->host_get_data.result = NULL;
182   SIMIX_simcall_push(simcall->issuer);
183   return simcall->host_get_data.result;
184 }
185
186 /**
187  * \ingroup simix_host_management
188  * \brief Sets the user data associated to a host.
189  *
190  * The host must not have previous user data associated to it.
191  * \param host A SIMIX host
192  * \param data The user data to set
193  */
194 void simcall_host_set_data(smx_host_t host, void *data)
195 {
196   smx_simcall_t simcall = SIMIX_simcall_mine();
197
198   simcall->call = SIMCALL_HOST_SET_DATA;
199   simcall->host_set_data.host = host;
200   simcall->host_set_data.data = data;
201   SIMIX_simcall_push(simcall->issuer);
202 }
203
204 /**
205  * \ingroup simix_host_management
206  * \brief Creates an action that executes some computation of an host.
207  *
208  * This function creates a SURF action and allocates the data necessary
209  * to create the SIMIX action. It can raise a host_error exception if the host crashed.
210  *
211  * \param name Name of the execution action to create
212  * \param host SIMIX host where the action will be executed
213  * \param computation_amount amount Computation amount (in bytes)
214  * \param priority computation priority
215  * \return A new SIMIX execution action
216  */
217 smx_action_t simcall_host_execute(const char *name, smx_host_t host,
218                                     double computation_amount,
219                                     double priority)
220 {
221   /* checking for infinite values */
222   xbt_assert(isfinite(computation_amount), "computation_amount is not finite!");
223   xbt_assert(isfinite(priority), "priority is not finite!");
224   
225   smx_simcall_t simcall = SIMIX_simcall_mine();
226
227   simcall->call = SIMCALL_HOST_EXECUTE;
228   simcall->host_execute.name = name;
229   simcall->host_execute.host = host;
230   simcall->host_execute.computation_amount = computation_amount;
231   simcall->host_execute.priority = priority;
232   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
233     simcall->host_execute.result = NULL;
234   SIMIX_simcall_push(simcall->issuer);
235   return simcall->host_execute.result;
236 }
237
238 /**
239  * \ingroup simix_host_management
240  * \brief Creates an action that may involve parallel computation on
241  * several hosts and communication between them.
242  *
243  * \param name Name of the execution action to create
244  * \param host_nb Number of hosts where the action will be executed
245  * \param host_list Array (of size host_nb) of hosts where the action will be executed
246  * \param computation_amount Array (of size host_nb) of computation amount of hosts (in bytes)
247  * \param communication_amount Array (of size host_nb * host_nb) representing the communication
248  * amount between each pair of hosts
249  * \param amount the SURF action amount
250  * \param rate the SURF action rate
251  * \return A new SIMIX execution action
252  */
253 smx_action_t simcall_host_parallel_execute(const char *name,
254                                          int host_nb,
255                                          smx_host_t *host_list,
256                                          double *computation_amount,
257                                          double *communication_amount,
258                                          double amount,
259                                          double rate)
260 {
261   int i,j;
262   /* checking for infinite values */
263   for (i = 0 ; i < host_nb ; ++i) {
264      xbt_assert(isfinite(computation_amount[i]), "computation_amount[%d] is not finite!", i);
265      for (j = 0 ; j < host_nb ; ++j) {
266         xbt_assert(isfinite(communication_amount[i + host_nb * j]), 
267              "communication_amount[%d+%d*%d] is not finite!", i, host_nb, j);
268      }   
269   }   
270  
271   xbt_assert(isfinite(amount), "amount is not finite!");
272   xbt_assert(isfinite(rate), "rate is not finite!");
273   
274   smx_simcall_t simcall = SIMIX_simcall_mine();
275
276   simcall->call = SIMCALL_HOST_PARALLEL_EXECUTE;
277   simcall->host_parallel_execute.name = name;
278   simcall->host_parallel_execute.host_nb = host_nb;
279   simcall->host_parallel_execute.host_list = host_list;
280   simcall->host_parallel_execute.computation_amount = computation_amount;
281   simcall->host_parallel_execute.communication_amount = communication_amount;
282   simcall->host_parallel_execute.amount = amount;
283   simcall->host_parallel_execute.rate = rate;
284   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
285     simcall->host_parallel_execute.result = NULL;
286   SIMIX_simcall_push(simcall->issuer);
287   return simcall->host_parallel_execute.result;
288 }
289
290 /**
291  * \ingroup simix_host_management
292  * \brief Destroys an execution action.
293  *
294  * Destroys an action, freing its memory. This function cannot be called if there are a conditional waiting for it.
295  * \param execution The execution action to destroy
296  */
297 void simcall_host_execution_destroy(smx_action_t execution)
298 {
299   smx_simcall_t simcall = SIMIX_simcall_mine();
300
301   simcall->call = SIMCALL_HOST_EXECUTION_DESTROY;
302   simcall->host_execution_destroy.execution = execution;
303   SIMIX_simcall_push(simcall->issuer);
304 }
305
306 /**
307  * \ingroup simix_host_management
308  * \brief Cancels an execution action.
309  *
310  * This functions stops the execution. It calls a surf function.
311  * \param execution The execution action to cancel
312  */
313 void simcall_host_execution_cancel(smx_action_t execution)
314 {
315   smx_simcall_t simcall = SIMIX_simcall_mine();
316
317   simcall->call = SIMCALL_HOST_EXECUTION_CANCEL;
318   simcall->host_execution_cancel.execution = execution;
319   SIMIX_simcall_push(simcall->issuer);
320 }
321
322 /**
323  * \ingroup simix_host_management
324  * \brief Returns how much of an execution action remains to be done.
325  *
326  * \param execution The execution action
327  * \return The remaining amount
328  */
329 double simcall_host_execution_get_remains(smx_action_t execution)
330 {
331   smx_simcall_t simcall = SIMIX_simcall_mine();
332
333   simcall->call = SIMCALL_HOST_EXECUTION_GET_REMAINS;
334   simcall->host_execution_get_remains.execution = execution;
335   if(MC_IS_ENABLED) /* Initializeialize result to a default value for snapshot comparison done during simcall */
336     simcall->host_execution_get_remains.result = 0.0;
337   SIMIX_simcall_push(simcall->issuer);
338   return simcall->host_execution_get_remains.result;
339 }
340
341 /**
342  * \ingroup simix_host_management
343  * \brief Returns the state of an execution action.
344  *
345  * \param execution The execution action
346  * \return The state
347  */
348 e_smx_state_t simcall_host_execution_get_state(smx_action_t execution)
349 {
350   smx_simcall_t simcall = SIMIX_simcall_mine();
351
352   simcall->call = SIMCALL_HOST_EXECUTION_GET_STATE;
353   simcall->host_execution_get_state.execution = execution;
354   simcall->host_execution_get_state.result = -1;
355   SIMIX_simcall_push(simcall->issuer);
356   return simcall->host_execution_get_state.result;
357 }
358
359 /**
360  * \ingroup simix_host_management
361  * \brief Changes the priority of an execution action.
362  *
363  * This functions changes the priority only. It calls a surf function.
364  * \param execution The execution action
365  * \param priority The new priority
366  */
367 void simcall_host_execution_set_priority(smx_action_t execution, double priority)
368 {
369   /* checking for infinite values */
370   xbt_assert(isfinite(priority), "priority is not finite!");
371   
372   smx_simcall_t simcall = SIMIX_simcall_mine();
373
374   simcall->call = SIMCALL_HOST_EXECUTION_SET_PRIORITY;
375   simcall->host_execution_set_priority.execution = execution;
376   simcall->host_execution_set_priority.priority = priority;
377   SIMIX_simcall_push(simcall->issuer);
378 }
379
380 /**
381  * \ingroup simix_host_management
382  * \brief Waits for the completion of an execution action and destroy it.
383  *
384  * \param execution The execution action
385  */
386 e_smx_state_t simcall_host_execution_wait(smx_action_t execution)
387 {
388   smx_simcall_t simcall = SIMIX_simcall_mine();
389
390   simcall->call = SIMCALL_HOST_EXECUTION_WAIT;
391   simcall->host_execution_wait.execution = execution;
392   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
393     simcall->host_execution_wait.result = -1;
394   SIMIX_simcall_push(simcall->issuer);
395   return simcall->host_execution_wait.result;
396 }
397
398 /**
399  * \ingroup simix_process_management
400  * \brief Creates and runs a new SIMIX process.
401  *
402  * The structure and the corresponding thread are created and put in the list of ready processes.
403  *
404  * \param process the process created will be stored in this pointer
405  * \param name a name for the process. It is for user-level information and can be NULL.
406  * \param code the main function of the process
407  * \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.
408  * It can be retrieved with the function \ref simcall_process_get_data.
409  * \param hostname name of the host where the new agent is executed.
410  * \param kill_time time when the process is killed
411  * \param argc first argument passed to \a code
412  * \param argv second argument passed to \a code
413  * \param properties the properties of the process
414  * \param auto_restart either it is autorestarting or not.
415  */
416 void simcall_process_create(smx_process_t *process, const char *name,
417                               xbt_main_func_t code,
418                               void *data,
419                               const char *hostname,
420                               double kill_time,
421                               int argc, char **argv,
422                               xbt_dict_t properties,
423                               int auto_restart)
424 {
425   smx_simcall_t simcall = SIMIX_simcall_mine();
426
427   simcall->call = SIMCALL_PROCESS_CREATE;
428   simcall->process_create.process = process;
429   simcall->process_create.name = name;
430   simcall->process_create.code = code;
431   simcall->process_create.data = data;
432   simcall->process_create.hostname = hostname;
433   simcall->process_create.kill_time = kill_time;
434   simcall->process_create.argc = argc;
435   simcall->process_create.argv = argv;
436   simcall->process_create.properties = properties;
437   simcall->process_create.auto_restart = auto_restart;
438   SIMIX_simcall_push(simcall->issuer);
439 }
440
441 /**
442  * \ingroup simix_process_management
443  * \brief Kills a SIMIX process.
444  *
445  * This function simply kills a  process.
446  *
447  * \param process poor victim
448  */
449 void simcall_process_kill(smx_process_t process)
450 {
451   smx_simcall_t simcall = SIMIX_simcall_mine();
452
453   simcall->call = SIMCALL_PROCESS_KILL;
454   simcall->process_kill.process = process;
455   SIMIX_simcall_push(simcall->issuer);
456 }
457
458 /**
459  * \ingroup simix_process_management
460  * \brief Kills all SIMIX processes.
461  */
462 void simcall_process_killall(void)
463 {
464   smx_simcall_t simcall = SIMIX_simcall_mine();
465
466   simcall->call = SIMCALL_PROCESS_KILLALL;
467   SIMIX_simcall_push(simcall->issuer);
468 }
469
470 /**
471  * \ingroup simix_process_management
472  * \brief Cleans up a SIMIX process.
473  * \param process poor victim (must have already been killed)
474  */
475 void simcall_process_cleanup(smx_process_t process)
476 {
477   smx_simcall_t simcall = SIMIX_simcall_mine();
478
479   simcall->call = SIMCALL_PROCESS_CLEANUP;
480   simcall->process_cleanup.process = process;
481   SIMIX_simcall_push(simcall->issuer);
482 }
483
484 /**
485  * \ingroup simix_process_management
486  * \brief Migrates an agent to another location.
487  *
488  * This function changes the value of the host on which \a process is running.
489  *
490  * \param process the process to migrate
491  * \param dest name of the new host
492  */
493 void simcall_process_change_host(smx_process_t process, smx_host_t dest)
494 {
495   smx_simcall_t simcall = SIMIX_simcall_mine();
496
497   simcall->call = SIMCALL_PROCESS_CHANGE_HOST;
498   simcall->process_change_host.process = process;
499   simcall->process_change_host.dest = dest;
500   SIMIX_simcall_push(simcall->issuer);
501 }
502
503 /**
504  * \ingroup simix_process_management
505  * \brief Suspends a process.
506  *
507  * This function suspends the process by suspending the action
508  * it was waiting for completion.
509  *
510  * \param process a SIMIX process
511  */
512 void simcall_process_suspend(smx_process_t process)
513 {
514   xbt_assert(process, "Invalid parameters");
515
516   smx_simcall_t simcall = SIMIX_simcall_mine();
517
518   simcall->call = SIMCALL_PROCESS_SUSPEND;
519   simcall->process_suspend.process = process;
520   SIMIX_simcall_push(simcall->issuer);
521 }
522
523 /**
524  * \ingroup simix_process_management
525  * \brief Resumes a suspended process.
526  *
527  * This function resumes a suspended process by resuming the action
528  * it was waiting for completion.
529  *
530  * \param process a SIMIX process
531  */
532 void simcall_process_resume(smx_process_t process)
533 {
534   smx_simcall_t simcall = SIMIX_simcall_mine();
535
536   simcall->call = SIMCALL_PROCESS_RESUME;
537   simcall->process_resume.process = process;
538   SIMIX_simcall_push(simcall->issuer);
539 }
540
541 /**
542  * \ingroup simix_process_management
543  * \brief Returns the amount of SIMIX processes in the system
544  *
545  * Maestro internal process is not counted, only user code processes are
546  */
547 int simcall_process_count(void)
548 {
549   smx_simcall_t simcall = SIMIX_simcall_mine();
550
551   simcall->call = SIMCALL_PROCESS_COUNT;
552   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
553     simcall->process_count.result = -1;
554   SIMIX_simcall_push(simcall->issuer);
555   return simcall->process_count.result;
556 }
557
558 /**
559  * \ingroup simix_process_management
560  * \brief Return the user data of a #smx_process_t.
561  * \param process a SIMIX process
562  * \return the user data of this process
563  */
564 void* simcall_process_get_data(smx_process_t process)
565 {
566   if (process == SIMIX_process_self()) {
567     /* avoid a simcall if this function is called by the process itself */
568     return SIMIX_process_get_data(process);
569   }
570
571   smx_simcall_t simcall = SIMIX_simcall_mine();
572
573   simcall->call = SIMCALL_PROCESS_GET_DATA;
574   simcall->process_get_data.process = process;
575   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
576     simcall->process_get_data.result = NULL;
577   SIMIX_simcall_push(simcall->issuer);
578   return simcall->process_get_data.result;
579 }
580
581 /**
582  * \ingroup simix_process_management
583  * \brief Set the user data of a #smx_process_t.
584  *
585  * This functions sets the user data associated to \a process.
586  * \param process SIMIX process
587  * \param data User data
588  */
589 void simcall_process_set_data(smx_process_t process, void *data)
590 {
591   if (process == SIMIX_process_self()) {
592     /* avoid a simcall if this function is called by the process itself */
593     SIMIX_process_self_set_data(process, data);
594   }
595   else {
596
597     smx_simcall_t simcall = SIMIX_simcall_mine();
598
599     simcall->call = SIMCALL_PROCESS_SET_DATA;
600     simcall->process_set_data.process = process;
601     simcall->process_set_data.data = data;
602     SIMIX_simcall_push(simcall->issuer);
603   }
604 }
605
606 /**
607  * \ingroup simix_process_management
608  * \brief Set the kill time of a process.
609  * \param process a process
610  * \param kill_time a double
611  */
612 void simcall_process_set_kill_time(smx_process_t process, double kill_time)
613 {
614
615   if (kill_time > SIMIX_get_clock()) {
616     if (simix_global->kill_process_function) {
617       XBT_DEBUG("Set kill time %f for process %s(%s)",kill_time, process->name,
618           process->smx_host->name);
619       SIMIX_timer_set(kill_time, simix_global->kill_process_function, process);
620     }
621   }
622 }
623
624 /**
625  * \ingroup simix_process_management
626  * \brief Return the location on which an agent is running.
627  *
628  * This functions returns the smx_host_t corresponding to the location on which
629  * \a process is running.
630  * \param process SIMIX process
631  * \return SIMIX host
632  */
633 smx_host_t simcall_process_get_host(smx_process_t process)
634 {
635   smx_simcall_t simcall = SIMIX_simcall_mine();
636
637   simcall->call = SIMCALL_PROCESS_GET_HOST;
638   simcall->process_get_host.process = process;
639   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
640     simcall->process_get_host.result = NULL;
641   SIMIX_simcall_push(simcall->issuer);
642   return simcall->process_get_host.result;
643 }
644
645 /**
646  * \ingroup simix_process_management
647  * \brief Return the name of an agent.
648  *
649  * This functions checks whether \a process is a valid pointer or not and return its name.
650  * \param process SIMIX process
651  * \return The process name
652  */
653 const char* simcall_process_get_name(smx_process_t process)
654 {
655   if (process == SIMIX_process_self()) {
656     /* avoid a simcall if this function is called by the process itself */
657     return process->name;
658   }
659
660   smx_simcall_t simcall = SIMIX_simcall_mine();
661
662   simcall->call = SIMCALL_PROCESS_GET_NAME;
663   simcall->process_get_name.process = process;
664   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
665     simcall->process_get_name.result = NULL;
666   SIMIX_simcall_push(simcall->issuer);
667   return simcall->process_get_name.result;
668 }
669
670 /**
671  * \ingroup simix_process_management
672  * \brief Returns true if the process is suspended .
673  *
674  * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
675  * \param process SIMIX process
676  * \return 1, if the process is suspended, else 0.
677  */
678 int simcall_process_is_suspended(smx_process_t process)
679 {
680   smx_simcall_t simcall = SIMIX_simcall_mine();
681
682   simcall->call = SIMCALL_PROCESS_IS_SUSPENDED;
683   simcall->process_is_suspended.process = process;
684   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
685     simcall->process_is_suspended.result = -1;
686   SIMIX_simcall_push(simcall->issuer);
687   return simcall->process_is_suspended.result;
688 }
689
690 /**
691  * \ingroup simix_process_management
692  * \brief Return the properties
693  *
694  * This functions returns the properties associated with this process
695  */
696 xbt_dict_t simcall_process_get_properties(smx_process_t process)
697 {
698   smx_simcall_t simcall = SIMIX_simcall_mine();
699
700   simcall->call = SIMCALL_PROCESS_GET_PROPERTIES;
701   simcall->process_get_properties.process = process;
702   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
703     simcall->process_get_properties.result = NULL;
704   SIMIX_simcall_push(simcall->issuer);
705   return simcall->process_get_properties.result;
706 }
707 /**
708  * \ingroup simix_process_management
709  * \brief Add an on_exit function
710  * Add an on_exit function which will be executed when the process exits/is killed.
711  */
712 XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
713 {
714   smx_simcall_t simcall = SIMIX_simcall_mine();
715
716   simcall->call = SIMCALL_PROCESS_ON_EXIT;
717   simcall->process_on_exit.process = process;
718   simcall->process_on_exit.fun = fun;
719   simcall->process_on_exit.data = data;
720
721   SIMIX_simcall_push(simcall->issuer);
722 }
723 /**
724  * \ingroup simix_process_management
725  * \brief Sets the process to be auto-restarted or not by SIMIX when its host comes back up.
726  * Will restart the process when the host comes back up if auto_restart is set to 1.
727  */
728
729 XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart)
730 {
731   smx_simcall_t simcall = SIMIX_simcall_mine();
732
733   simcall->call = SIMCALL_PROCESS_AUTO_RESTART_SET;
734   simcall->process_auto_restart.process = process;
735   simcall->process_auto_restart.auto_restart = auto_restart;
736
737   SIMIX_simcall_push(simcall->issuer);
738 }
739 /**
740  * \ingroup simix_process_management
741  * \brief Restarts the process, killing it and starting it again from scratch.
742  */
743 XBT_PUBLIC(smx_process_t) simcall_process_restart(smx_process_t process)
744 {
745   smx_simcall_t simcall = SIMIX_simcall_mine();
746
747   simcall->call = SIMCALL_PROCESS_RESTART;
748   simcall->process_restart.process = process;
749   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
750     simcall->process_restart.result = NULL;
751
752   SIMIX_simcall_push(simcall->issuer);
753
754   return simcall->process_restart.result;
755 }
756 /**
757  * \ingroup simix_process_management
758  * \brief Creates a new sleep SIMIX action.
759  *
760  * This function creates a SURF action and allocates the data necessary
761  * to create the SIMIX action. It can raise a host_error exception if the
762  * host crashed. The default SIMIX name of the action is "sleep".
763  *
764  *   \param duration Time duration of the sleep.
765  *   \return A result telling whether the sleep was successful
766  */
767 e_smx_state_t simcall_process_sleep(double duration)
768 {
769   /* checking for infinite values */
770   xbt_assert(isfinite(duration), "duration is not finite!");
771   
772   smx_simcall_t simcall = SIMIX_simcall_mine();
773
774   simcall->call = SIMCALL_PROCESS_SLEEP;
775   simcall->process_sleep.duration = duration;
776   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
777     simcall->process_sleep.result = -1;
778   SIMIX_simcall_push(simcall->issuer);
779   return simcall->process_sleep.result;
780 }
781
782 /**
783  *  \ingroup simix_rdv_management
784  *  \brief Creates a new rendez-vous point
785  *  \param name The name of the rendez-vous point
786  *  \return The created rendez-vous point
787  */
788 smx_rdv_t simcall_rdv_create(const char *name)
789 {
790   smx_simcall_t simcall = SIMIX_simcall_mine();
791
792   simcall->call = SIMCALL_RDV_CREATE;
793   simcall->rdv_create.name = name;
794   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
795     simcall->rdv_create.result = NULL;
796
797   SIMIX_simcall_push(simcall->issuer);
798   return simcall->rdv_create.result;
799 }
800
801
802 /**
803  *  \ingroup simix_rdv_management
804  *  \brief Destroy a rendez-vous point
805  *  \param rdv The rendez-vous point to destroy
806  */
807 void simcall_rdv_destroy(smx_rdv_t rdv)
808 {
809   smx_simcall_t simcall = SIMIX_simcall_mine();
810
811   simcall->call = SIMCALL_RDV_DESTROY;
812   simcall->rdv_destroy.rdv = rdv;
813
814   SIMIX_simcall_push(simcall->issuer);
815 }
816 /**
817  *  \ingroup simix_rdv_management
818  *  \brief Returns a rendez-vous point knowing its name
819  */
820 smx_rdv_t simcall_rdv_get_by_name(const char *name)
821 {
822   xbt_assert(name != NULL, "Invalid parameter for simcall_rdv_get_by_name (name is NULL)");
823
824   /* FIXME: this is a horrible lost of performance, so we hack it out by
825    * skipping the simcall (for now). It works in parallel, it won't work on
826    * distributed but probably we will change MSG for that. */
827
828   /*
829   smx_simcall_t simcall = simcall_mine();
830   simcall->call = SIMCALL_RDV_GEY_BY_NAME;
831   simcall->rdv_get_by_name.name = name;
832   SIMIX_simcall_push(simcall->issuer);
833   return simcall->rdv_get_by_name.result;*/
834
835   return SIMIX_rdv_get_by_name(name);
836 }
837
838 /**
839  *  \ingroup simix_rdv_management
840  *  \brief Counts the number of communication actions of a given host pending
841  *         on a rendez-vous point.
842  *  \param rdv The rendez-vous point
843  *  \param host The host to be counted
844  *  \return The number of comm actions pending in the rdv
845  */
846 int simcall_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
847 {
848   smx_simcall_t simcall = SIMIX_simcall_mine();
849
850   simcall->call = SIMCALL_RDV_COMM_COUNT_BY_HOST;
851   simcall->rdv_comm_count_by_host.rdv = rdv;
852   simcall->rdv_comm_count_by_host.host = host;
853   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
854     simcall->rdv_comm_count_by_host.result = -1;
855
856   SIMIX_simcall_push(simcall->issuer);
857   return simcall->rdv_comm_count_by_host.result;
858 }
859
860 /**
861  *  \ingroup simix_rdv_management
862  *  \brief returns the communication at the head of the rendez-vous
863  *  \param rdv The rendez-vous point
864  *  \return The communication or NULL if empty
865  */
866 smx_action_t simcall_rdv_get_head(smx_rdv_t rdv)
867 {
868   smx_simcall_t simcall = SIMIX_simcall_mine();
869
870   simcall->call = SIMCALL_RDV_GET_HEAD;
871   simcall->rdv_get_head.rdv = rdv;
872   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
873     simcall->rdv_get_head.result = NULL;
874
875   SIMIX_simcall_push(simcall->issuer);
876   return simcall->rdv_get_head.result;
877 }
878
879 void simcall_rdv_set_receiver(smx_rdv_t rdv , smx_process_t process)
880 {
881   smx_simcall_t simcall = SIMIX_simcall_mine();
882
883   simcall->call = SIMCALL_RDV_SET_RECV;
884   simcall->rdv_set_rcv_proc.rdv = rdv;
885   simcall->rdv_set_rcv_proc.receiver = process;
886
887   SIMIX_simcall_push(simcall->issuer);
888 }
889
890 smx_process_t simcall_rdv_get_receiver(smx_rdv_t rdv)
891 {
892   smx_simcall_t simcall = SIMIX_simcall_mine();
893
894   simcall->call = SIMCALL_RDV_GET_RECV;
895   simcall->rdv_get_rcv_proc.rdv = rdv;
896   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
897     simcall->rdv_get_rcv_proc.result = NULL;
898
899   SIMIX_simcall_push(simcall->issuer);
900   return simcall->rdv_get_rcv_proc.result;
901 }
902
903 /**
904  * \ingroup simix_comm_management
905  */
906 void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
907                          void *src_buff, size_t src_buff_size,
908                          int (*match_fun)(void *, void *, smx_action_t), void *data,
909                          double timeout)
910 {
911   /* checking for infinite values */
912   xbt_assert(isfinite(task_size), "task_size is not finite!");
913   xbt_assert(isfinite(rate), "rate is not finite!");
914   xbt_assert(isfinite(timeout), "timeout is not finite!");
915   
916   xbt_assert(rdv, "No rendez-vous point defined for send");
917
918   if (MC_IS_ENABLED) {
919     /* the model-checker wants two separate simcalls */
920     smx_action_t comm = simcall_comm_isend(rdv, task_size, rate,
921         src_buff, src_buff_size, match_fun, NULL, data, 0);
922     simcall_comm_wait(comm, timeout);
923   }
924   else {
925     smx_simcall_t simcall = SIMIX_simcall_mine();
926
927     simcall->call = SIMCALL_COMM_SEND;
928     simcall->comm_send.rdv = rdv;
929     simcall->comm_send.task_size = task_size;
930     simcall->comm_send.rate = rate;
931     simcall->comm_send.src_buff = src_buff;
932     simcall->comm_send.src_buff_size = src_buff_size;
933     simcall->comm_send.match_fun = match_fun;
934     simcall->comm_send.data = data;
935     simcall->comm_send.timeout = timeout;
936
937     SIMIX_simcall_push(simcall->issuer);
938   }
939 }
940 /**
941  * \ingroup simix_comm_management
942  */
943 smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
944                               void *src_buff, size_t src_buff_size,
945                               int (*match_fun)(void *, void *, smx_action_t),
946                               void (*clean_fun)(void *),
947                               void *data,
948                               int detached)
949 {
950   /* checking for infinite values */
951   xbt_assert(isfinite(task_size), "task_size is not finite!");
952   xbt_assert(isfinite(rate), "rate is not finite!");
953   
954   xbt_assert(rdv, "No rendez-vous point defined for isend");
955
956   smx_simcall_t simcall = SIMIX_simcall_mine();
957
958   simcall->call = SIMCALL_COMM_ISEND;
959   simcall->comm_isend.rdv = rdv;
960   simcall->comm_isend.task_size = task_size;
961   simcall->comm_isend.rate = rate;
962   simcall->comm_isend.src_buff = src_buff;
963   simcall->comm_isend.src_buff_size = src_buff_size;
964   simcall->comm_isend.match_fun = match_fun;
965   simcall->comm_isend.clean_fun = clean_fun;
966   simcall->comm_isend.data = data;
967   simcall->comm_isend.detached = detached;
968   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
969     simcall->comm_isend.result = NULL;
970
971   SIMIX_simcall_push(simcall->issuer);
972   return simcall->comm_isend.result;
973 }
974 /**
975  * \ingroup simix_comm_management
976  */
977 void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
978                          int (*match_fun)(void *, void *, smx_action_t), void *data, double timeout)
979 {
980   xbt_assert(isfinite(timeout), "timeout is not finite!");
981   xbt_assert(rdv, "No rendez-vous point defined for recv");
982
983   if (MC_IS_ENABLED) {
984     /* the model-checker wants two separate simcalls */
985     smx_action_t comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
986         match_fun, data);
987     simcall_comm_wait(comm, timeout);
988   }
989   else {
990     smx_simcall_t simcall = SIMIX_simcall_mine();
991
992     simcall->call = SIMCALL_COMM_RECV;
993     simcall->comm_recv.rdv = rdv;
994     simcall->comm_recv.dst_buff = dst_buff;
995     simcall->comm_recv.dst_buff_size = dst_buff_size;
996     simcall->comm_recv.match_fun = match_fun;
997     simcall->comm_recv.data = data;
998     simcall->comm_recv.timeout = timeout;
999
1000     SIMIX_simcall_push(simcall->issuer);
1001   }
1002 }
1003 /**
1004  * \ingroup simix_comm_management
1005  */
1006 smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
1007                                   int (*match_fun)(void *, void *, smx_action_t), void *data)
1008 {
1009   xbt_assert(rdv, "No rendez-vous point defined for irecv");
1010
1011   smx_simcall_t simcall = SIMIX_simcall_mine();
1012
1013   simcall->call = SIMCALL_COMM_IRECV;
1014   simcall->comm_irecv.rdv = rdv;
1015   simcall->comm_irecv.dst_buff = dst_buff;
1016   simcall->comm_irecv.dst_buff_size = dst_buff_size;
1017   simcall->comm_irecv.match_fun = match_fun;
1018   simcall->comm_irecv.data = data;
1019   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1020     simcall->comm_irecv.result = NULL;
1021
1022   SIMIX_simcall_push(simcall->issuer);
1023   return simcall->comm_irecv.result;
1024 }
1025
1026
1027 /**
1028  * \ingroup simix_comm_management
1029  */
1030 smx_action_t simcall_comm_iprobe(smx_rdv_t rdv, int src, int tag,
1031                                 int (*match_fun)(void *, void *, smx_action_t), void *data)
1032 {
1033   xbt_assert(rdv, "No rendez-vous point defined for iprobe");
1034
1035   smx_simcall_t simcall = SIMIX_simcall_mine();
1036
1037   simcall->call = SIMCALL_COMM_IPROBE;
1038   simcall->comm_iprobe.rdv = rdv;
1039   simcall->comm_iprobe.src = src;
1040   simcall->comm_iprobe.match_fun = match_fun;
1041   simcall->comm_iprobe.data = data;
1042   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1043     simcall->comm_iprobe.result = NULL;
1044   SIMIX_simcall_push(simcall->issuer);
1045   return simcall->comm_iprobe.result;
1046 }
1047
1048
1049 void simcall_comm_destroy(smx_action_t comm)
1050 {
1051   xbt_assert(comm, "Invalid parameter");
1052
1053   /* FIXME remove this simcall type: comms are auto-destroyed now */
1054
1055   /*
1056   smx_simcall_t simcall = simcall_mine();
1057
1058   simcall->call = SIMCALL_COMM_DESTROY;
1059   simcall->comm_destroy.comm = comm;
1060
1061   SIMIX_simcall_push(simcall->issuer);
1062   */
1063 }
1064 /**
1065  * \ingroup simix_comm_management
1066  */
1067 void simcall_comm_cancel(smx_action_t comm)
1068 {
1069   smx_simcall_t simcall = SIMIX_simcall_mine();
1070
1071   simcall->call = SIMCALL_COMM_CANCEL;
1072   simcall->comm_cancel.comm = comm;
1073
1074   SIMIX_simcall_push(simcall->issuer);
1075 }
1076 /**
1077  * \ingroup simix_comm_management
1078  */
1079 unsigned int simcall_comm_waitany(xbt_dynar_t comms)
1080 {
1081   smx_simcall_t simcall = SIMIX_simcall_mine();
1082
1083   simcall->call = SIMCALL_COMM_WAITANY;
1084   simcall->comm_waitany.comms = comms;
1085   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1086     simcall->comm_waitany.result = -1;
1087
1088   SIMIX_simcall_push(simcall->issuer);
1089   return simcall->comm_waitany.result;
1090 }
1091 /**
1092  * \ingroup simix_comm_management
1093  */
1094 int simcall_comm_testany(xbt_dynar_t comms)
1095 {
1096   smx_simcall_t simcall = SIMIX_simcall_mine();
1097   if (xbt_dynar_is_empty(comms))
1098     return -1;
1099
1100   simcall->call = SIMCALL_COMM_TESTANY;
1101   simcall->comm_testany.comms = comms;
1102     if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1103       simcall->comm_testany.result = -1;
1104
1105   SIMIX_simcall_push(simcall->issuer);
1106   return simcall->comm_testany.result;
1107 }
1108 /**
1109  * \ingroup simix_comm_management
1110  */
1111 void simcall_comm_wait(smx_action_t comm, double timeout)
1112 {
1113   xbt_assert(isfinite(timeout), "timeout is not finite!");
1114   
1115   smx_simcall_t simcall = SIMIX_simcall_mine();
1116
1117   simcall->call = SIMCALL_COMM_WAIT;
1118   simcall->comm_wait.comm = comm;
1119   simcall->comm_wait.timeout = timeout;
1120
1121   SIMIX_simcall_push(simcall->issuer);
1122 }
1123
1124 #ifdef HAVE_TRACING
1125 /**
1126  * \brief Set the category of an action.
1127  *
1128  * This functions changes the category only. It calls a surf function.
1129  * \param execution The execution action
1130  * \param category The tracing category
1131  */
1132 void simcall_set_category(smx_action_t action, const char *category)
1133 {
1134   if (category == NULL) {
1135     return;
1136   }
1137
1138   smx_simcall_t simcall = SIMIX_simcall_mine();
1139
1140   simcall->call = SIMCALL_SET_CATEGORY;
1141   simcall->set_category.action = action;
1142   simcall->set_category.category = category;
1143
1144   SIMIX_simcall_push(simcall->issuer);
1145 }
1146 #endif
1147 /**
1148  * \ingroup simix_comm_management
1149  *
1150  */
1151 int simcall_comm_test(smx_action_t comm)
1152 {
1153   smx_simcall_t simcall = SIMIX_simcall_mine();
1154
1155   simcall->call = SIMCALL_COMM_TEST;
1156   simcall->comm_test.comm = comm;
1157   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1158     simcall->comm_test.result = -1;
1159
1160   SIMIX_simcall_push(simcall->issuer);
1161   return simcall->comm_test.result;
1162 }
1163 /**
1164  * \ingroup simix_comm_management
1165  *
1166  */
1167 double simcall_comm_get_remains(smx_action_t comm)
1168 {
1169   smx_simcall_t simcall = SIMIX_simcall_mine();
1170
1171   simcall->call = SIMCALL_COMM_GET_REMAINS;
1172   simcall->comm_get_remains.comm = comm;
1173   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1174     simcall->comm_get_remains.result = 0.0;
1175
1176   SIMIX_simcall_push(simcall->issuer);
1177   return simcall->comm_get_remains.result;
1178 }
1179 /**
1180  * \ingroup simix_comm_management
1181  *
1182  */
1183 e_smx_state_t simcall_comm_get_state(smx_action_t comm)
1184 {
1185   smx_simcall_t simcall = SIMIX_simcall_mine();
1186
1187   simcall->call = SIMCALL_COMM_GET_STATE;
1188   simcall->comm_get_state.comm = comm;
1189   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1190     simcall->comm_get_state.result = -1;
1191
1192   SIMIX_simcall_push(simcall->issuer);
1193   return simcall->comm_get_state.result;
1194 }
1195 /**
1196  * \ingroup simix_comm_management
1197  *
1198  */
1199 void *simcall_comm_get_src_data(smx_action_t comm)
1200 {
1201   smx_simcall_t simcall = SIMIX_simcall_mine();
1202
1203   simcall->call = SIMCALL_COMM_GET_SRC_DATA;
1204   simcall->comm_get_src_data.comm = comm;
1205   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1206     simcall->comm_get_src_data.result = NULL;
1207
1208   SIMIX_simcall_push(simcall->issuer);
1209   return simcall->comm_get_src_data.result;
1210 }
1211 /**
1212  * \ingroup simix_comm_management
1213  *
1214  */
1215 void *simcall_comm_get_dst_data(smx_action_t comm)
1216 {
1217   smx_simcall_t simcall = SIMIX_simcall_mine();
1218
1219   simcall->call = SIMCALL_COMM_GET_DST_DATA;
1220   simcall->comm_get_dst_data.comm = comm;
1221   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1222     simcall->comm_get_dst_data.result = NULL;
1223
1224   SIMIX_simcall_push(simcall->issuer);
1225   return simcall->comm_get_dst_data.result;
1226 }
1227 /**
1228  * \ingroup simix_comm_management
1229  *
1230  */
1231 smx_process_t simcall_comm_get_src_proc(smx_action_t comm)
1232 {
1233   smx_simcall_t simcall = SIMIX_simcall_mine();
1234
1235   simcall->call = SIMCALL_COMM_GET_SRC_PROC;
1236   simcall->comm_get_src_proc.comm = comm;
1237   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1238     simcall->comm_get_src_proc.result = NULL;
1239
1240   SIMIX_simcall_push(simcall->issuer);
1241   return simcall->comm_get_src_proc.result;
1242 }
1243 /**
1244  * \ingroup simix_comm_management
1245  *
1246  */
1247 smx_process_t simcall_comm_get_dst_proc(smx_action_t comm)
1248 {
1249   smx_simcall_t simcall = SIMIX_simcall_mine();
1250
1251   simcall->call = SIMCALL_COMM_GET_DST_PROC;
1252   simcall->comm_get_dst_proc.comm = comm;
1253   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1254     simcall->comm_get_dst_proc.result = NULL;
1255
1256   SIMIX_simcall_push(simcall->issuer);
1257   return simcall->comm_get_dst_proc.result;
1258 }
1259
1260 #ifdef HAVE_LATENCY_BOUND_TRACKING
1261 int simcall_comm_is_latency_bounded(smx_action_t comm)
1262 {
1263   smx_simcall_t simcall = SIMIX_simcall_mine();
1264
1265   simcall->call = SIMCALL_COMM_IS_LATENCY_BOUNDED;
1266   simcall->comm_is_latency_bounded.comm = comm;
1267   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1268     simcall->comm_is_latency_bounded.result = -1;
1269
1270   SIMIX_simcall_push(simcall->issuer);
1271   return simcall->comm_is_latency_bounded.result;
1272 }
1273 #endif
1274 /**
1275  * \ingroup simix_synchro_management
1276  *
1277  */
1278 smx_mutex_t simcall_mutex_init(void)
1279 {
1280   if(!simix_global) {
1281     fprintf(stderr,"You must run MSG_init or gras_init before using MSG or GRAS\n"); // I would have loved using xbt_die but I can't since it is not initialized yet... :)
1282     xbt_abort();
1283   }
1284   smx_simcall_t simcall = SIMIX_simcall_mine();
1285
1286   simcall->call = SIMCALL_MUTEX_INIT;
1287   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1288     simcall->mutex_init.result = NULL;
1289
1290   SIMIX_simcall_push(simcall->issuer);
1291   return simcall->mutex_init.result;
1292 }
1293 /**
1294  * \ingroup simix_synchro_management
1295  *
1296  */
1297 void simcall_mutex_destroy(smx_mutex_t mutex)
1298 {
1299   smx_simcall_t simcall = SIMIX_simcall_mine();
1300
1301   simcall->call = SIMCALL_MUTEX_DESTROY;
1302   simcall->mutex_destroy.mutex = mutex;
1303
1304   SIMIX_simcall_push(simcall->issuer);
1305 }
1306 /**
1307  * \ingroup simix_synchro_management
1308  *
1309  */
1310 void simcall_mutex_lock(smx_mutex_t mutex)
1311 {
1312   smx_simcall_t simcall = SIMIX_simcall_mine();
1313
1314   simcall->call = SIMCALL_MUTEX_LOCK;
1315   simcall->mutex_lock.mutex = mutex;
1316
1317   SIMIX_simcall_push(simcall->issuer);
1318 }
1319 /**
1320  * \ingroup simix_synchro_management
1321  *
1322  */
1323 int simcall_mutex_trylock(smx_mutex_t mutex)
1324 {
1325   smx_simcall_t simcall = SIMIX_simcall_mine();
1326
1327   simcall->call = SIMCALL_MUTEX_TRYLOCK;
1328   simcall->mutex_trylock.mutex = mutex;
1329   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1330     simcall->mutex_trylock.result = -1;
1331
1332   SIMIX_simcall_push(simcall->issuer);
1333   return simcall->mutex_trylock.result;
1334 }
1335 /**
1336  * \ingroup simix_synchro_management
1337  *
1338  */
1339 void simcall_mutex_unlock(smx_mutex_t mutex)
1340 {
1341   smx_simcall_t simcall = SIMIX_simcall_mine();
1342
1343   simcall->call = SIMCALL_MUTEX_UNLOCK;
1344   simcall->mutex_unlock.mutex = mutex;
1345
1346   SIMIX_simcall_push(simcall->issuer);
1347 }
1348 /**
1349  * \ingroup simix_synchro_management
1350  *
1351  */
1352 smx_cond_t simcall_cond_init(void)
1353 {
1354   smx_simcall_t simcall = SIMIX_simcall_mine();
1355
1356   simcall->call = SIMCALL_COND_INIT;
1357   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1358     simcall->cond_init.result = NULL;
1359
1360   SIMIX_simcall_push(simcall->issuer);
1361   return simcall->cond_init.result;
1362 }
1363 /**
1364  * \ingroup simix_synchro_management
1365  *
1366  */
1367 void simcall_cond_destroy(smx_cond_t cond)
1368 {
1369   smx_simcall_t simcall = SIMIX_simcall_mine();
1370
1371   simcall->call = SIMCALL_COND_DESTROY;
1372   simcall->cond_destroy.cond = cond;
1373
1374   SIMIX_simcall_push(simcall->issuer);
1375 }
1376 /**
1377  * \ingroup simix_synchro_management
1378  *
1379  */
1380 void simcall_cond_signal(smx_cond_t cond)
1381 {
1382   smx_simcall_t simcall = SIMIX_simcall_mine();
1383
1384   simcall->call = SIMCALL_COND_SIGNAL;
1385   simcall->cond_signal.cond = cond;
1386
1387   SIMIX_simcall_push(simcall->issuer);
1388 }
1389 /**
1390  * \ingroup simix_synchro_management
1391  *
1392  */
1393 void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
1394 {
1395   smx_simcall_t simcall = SIMIX_simcall_mine();
1396
1397   simcall->call = SIMCALL_COND_WAIT;
1398   simcall->cond_wait.cond = cond;
1399   simcall->cond_wait.mutex = mutex;
1400
1401   SIMIX_simcall_push(simcall->issuer);
1402 }
1403 /**
1404  * \ingroup simix_synchro_management
1405  *
1406  */
1407 void simcall_cond_wait_timeout(smx_cond_t cond,
1408                                  smx_mutex_t mutex,
1409                                  double timeout)
1410 {
1411   xbt_assert(isfinite(timeout), "timeout is not finite!");
1412   
1413   smx_simcall_t simcall = SIMIX_simcall_mine();
1414
1415   simcall->call = SIMCALL_COND_WAIT_TIMEOUT;
1416   simcall->cond_wait_timeout.cond = cond;
1417   simcall->cond_wait_timeout.mutex = mutex;
1418   simcall->cond_wait_timeout.timeout = timeout;
1419
1420   SIMIX_simcall_push(simcall->issuer);
1421 }
1422 /**
1423  * \ingroup simix_synchro_management
1424  *
1425  */
1426 void simcall_cond_broadcast(smx_cond_t cond)
1427 {
1428   smx_simcall_t simcall = SIMIX_simcall_mine();
1429
1430   simcall->call = SIMCALL_COND_BROADCAST;
1431   simcall->cond_broadcast.cond = cond;
1432
1433   SIMIX_simcall_push(simcall->issuer);
1434 }
1435 /**
1436  * \ingroup simix_synchro_management
1437  *
1438  */
1439 smx_sem_t simcall_sem_init(int capacity)
1440 {
1441   smx_simcall_t simcall = SIMIX_simcall_mine();
1442
1443   simcall->call = SIMCALL_SEM_INIT;
1444   simcall->sem_init.capacity = capacity;
1445   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1446     simcall->sem_init.result = NULL;
1447
1448   SIMIX_simcall_push(simcall->issuer);
1449   return simcall->sem_init.result;
1450 }
1451 /**
1452  * \ingroup simix_synchro_management
1453  *
1454  */
1455 void simcall_sem_destroy(smx_sem_t sem)
1456 {
1457   smx_simcall_t simcall = SIMIX_simcall_mine();
1458
1459   simcall->call = SIMCALL_SEM_DESTROY;
1460   simcall->sem_destroy.sem = sem;
1461
1462   SIMIX_simcall_push(simcall->issuer);
1463 }
1464 /**
1465  * \ingroup simix_synchro_management
1466  *
1467  */
1468 void simcall_sem_release(smx_sem_t sem)
1469 {
1470   smx_simcall_t simcall = SIMIX_simcall_mine();
1471
1472   simcall->call = SIMCALL_SEM_RELEASE;
1473   simcall->sem_release.sem = sem;
1474
1475   SIMIX_simcall_push(simcall->issuer);
1476 }
1477 /**
1478  * \ingroup simix_synchro_management
1479  *
1480  */
1481 int simcall_sem_would_block(smx_sem_t sem)
1482 {
1483   smx_simcall_t simcall = SIMIX_simcall_mine();
1484
1485   simcall->call = SIMCALL_SEM_WOULD_BLOCK;
1486   simcall->sem_would_block.sem = sem;
1487   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1488     simcall->sem_would_block.result = -1;
1489
1490   SIMIX_simcall_push(simcall->issuer);
1491   return simcall->sem_would_block.result;
1492 }
1493 /**
1494  * \ingroup simix_synchro_management
1495  *
1496  */
1497 void simcall_sem_acquire(smx_sem_t sem)
1498 {
1499   smx_simcall_t simcall = SIMIX_simcall_mine();
1500
1501   simcall->call = SIMCALL_SEM_ACQUIRE;
1502   simcall->sem_acquire.sem = sem;
1503
1504   SIMIX_simcall_push(simcall->issuer);
1505 }
1506 /**
1507  * \ingroup simix_synchro_management
1508  *
1509  */
1510 void simcall_sem_acquire_timeout(smx_sem_t sem, double timeout)
1511 {
1512   xbt_assert(isfinite(timeout), "timeout is not finite!");
1513   
1514   smx_simcall_t simcall = SIMIX_simcall_mine();
1515
1516   simcall->call = SIMCALL_SEM_ACQUIRE_TIMEOUT;
1517   simcall->sem_acquire_timeout.sem = sem;
1518   simcall->sem_acquire_timeout.timeout = timeout;
1519
1520   SIMIX_simcall_push(simcall->issuer);
1521 }
1522 /**
1523  * \ingroup simix_synchro_management
1524  *
1525  */
1526 int simcall_sem_get_capacity(smx_sem_t sem)
1527 {
1528   smx_simcall_t simcall = SIMIX_simcall_mine();
1529
1530   simcall->call = SIMCALL_SEM_GET_CAPACITY;
1531   simcall->sem_get_capacity.sem = sem;
1532   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1533     simcall->sem_get_capacity.result = -1;
1534
1535   SIMIX_simcall_push(simcall->issuer);
1536   return simcall->sem_get_capacity.result;
1537 }
1538 /**
1539  * \ingroup simix_file_management
1540  *
1541  */
1542 double simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1543 {
1544   smx_simcall_t simcall = SIMIX_simcall_mine();
1545
1546   simcall->call = SIMCALL_FILE_READ;
1547   simcall->file_read.ptr = ptr;
1548   simcall->file_read.size = size;
1549   simcall->file_read.nmemb = nmemb;
1550   simcall->file_read.stream = stream;
1551   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1552     simcall->file_read.result = 0.0;
1553   SIMIX_simcall_push(simcall->issuer);
1554
1555   return simcall->file_read.result;
1556 }
1557 /**
1558  * \ingroup simix_file_management
1559  *
1560  */
1561 size_t simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1562 {
1563   smx_simcall_t simcall = SIMIX_simcall_mine();
1564
1565   simcall->call = SIMCALL_FILE_WRITE;
1566   simcall->file_write.ptr = ptr;
1567   simcall->file_write.size = size;
1568   simcall->file_write.nmemb = nmemb;
1569   simcall->file_write.stream = stream;
1570   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1571     simcall->file_write.result = 0;
1572   SIMIX_simcall_push(simcall->issuer);
1573
1574   return simcall->file_write.result;
1575 }
1576 /**
1577  * \ingroup simix_file_management
1578  * \brief
1579  */
1580 smx_file_t simcall_file_open(const char* mount, const char* path, const char* mode)
1581 {
1582   smx_simcall_t simcall = SIMIX_simcall_mine();
1583
1584   simcall->call = SIMCALL_FILE_OPEN;
1585   simcall->file_open.mount = mount;
1586   simcall->file_open.path = path;
1587   simcall->file_open.mode = mode;
1588   if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1589     simcall->file_open.result = NULL;
1590   SIMIX_simcall_push(simcall->issuer);
1591
1592   return simcall->file_open.result;
1593 }
1594 /**
1595  * \ingroup simix_file_management
1596  *
1597  */
1598 int simcall_file_close(smx_file_t fp)
1599 {
1600   smx_simcall_t simcall = SIMIX_simcall_mine();
1601
1602   simcall->call = SIMCALL_FILE_CLOSE;
1603   simcall->file_close.fp = fp;
1604   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1605     simcall->file_close.result = -1;
1606   SIMIX_simcall_push(simcall->issuer);
1607
1608   return simcall->file_close.result;
1609 }
1610 /**
1611  * \ingroup simix_file_management
1612  *
1613  */
1614 int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
1615 {
1616   smx_simcall_t simcall = SIMIX_simcall_mine();
1617   simcall->call = SIMCALL_FILE_STAT;
1618   simcall->file_stat.fd = fd;
1619   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1620     simcall->file_stat.result = -1;
1621
1622   SIMIX_simcall_push(simcall->issuer);
1623
1624   *buf = simcall->file_stat.buf;
1625
1626   return simcall->file_stat.result;
1627 }
1628
1629 /**
1630  * \ingroup simix_file_management
1631  *
1632  */
1633 int simcall_file_unlink(smx_file_t fd)
1634 {
1635   smx_simcall_t simcall = SIMIX_simcall_mine();
1636   simcall->call = SIMCALL_FILE_UNLINK;
1637   simcall->file_unlink.fd = fd;
1638   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1639     simcall->file_unlink.result = -1;
1640
1641   SIMIX_simcall_push(simcall->issuer);
1642
1643   return simcall->file_unlink.result;
1644 }
1645
1646 /**
1647  * \ingroup simix_file_management
1648  *
1649  */
1650 xbt_dict_t simcall_file_ls(const char* mount, const char* path)
1651 {
1652   smx_simcall_t simcall = SIMIX_simcall_mine();
1653   simcall->call = SIMCALL_FILE_LS;
1654   simcall->file_ls.mount = mount;
1655   simcall->file_ls.path = path;
1656   if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1657     simcall->file_ls.result = NULL;
1658
1659   SIMIX_simcall_push(simcall->issuer);
1660
1661   return simcall->file_ls.result;
1662 }
1663
1664 /* ************************************************************************** */
1665
1666 /** @brief returns a printable string representing a simcall */
1667 const char *SIMIX_simcall_name(e_smx_simcall_t kind) {
1668   return simcall_names[kind];
1669 }