1 /* smx_user.c - public interface to simix */
3 /* Copyright (c) 2010, 2011. Da SimGrid team. All rights reserved. */
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. */
8 # define _SVID_SOURCE /* strdup() */
10 #ifndef _ISOC99_SOURCE
11 # define _ISOC99_SOURCE /* isfinite() */
13 #ifndef _ISO_C99_SOURCE
14 # define _ISO_C99_SOURCE /* isfinite() */
16 #include <math.h> /* isfinite() */
18 #include "smx_private.h"
22 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
24 static const char* simcall_names[] = {
25 #undef SIMCALL_ENUM_ELEMENT
26 #define SIMCALL_ENUM_ELEMENT(x) #x /* generate strings from the enumeration values */
28 #undef SIMCALL_ENUM_ELEMENT
32 * \ingroup simix_host_management
33 * \brief Returns a host given its name.
35 * \param name The name of the host to get
36 * \return The corresponding host
38 smx_host_t simcall_host_get_by_name(const char *name)
40 smx_simcall_t simcall = SIMIX_simcall_mine();
42 simcall->call = SIMCALL_HOST_GET_BY_NAME;
43 simcall->host_get_by_name.name = name;
44 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
45 simcall->host_get_by_name.result = NULL;
46 SIMIX_simcall_push(simcall->issuer);
47 return simcall->host_get_by_name.result;
51 * \ingroup simix_host_management
52 * \brief Returns the name of a host.
54 * \param host A SIMIX host
55 * \return The name of this host
57 const char* simcall_host_get_name(smx_host_t host)
59 smx_simcall_t simcall = SIMIX_simcall_mine();
61 simcall->call = SIMCALL_HOST_GET_NAME;
62 simcall->host_get_name.host = host;
63 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
64 simcall->host_get_name.result = NULL;
65 SIMIX_simcall_push(simcall->issuer);
66 return simcall->host_get_name.result;
70 * \ingroup simix_host_management
71 * \brief Returns a dict of the properties assigned to a host.
74 * \return The properties of this host
76 xbt_dict_t simcall_host_get_properties(smx_host_t host)
78 smx_simcall_t simcall = SIMIX_simcall_mine();
80 simcall->call = SIMCALL_HOST_GET_PROPERTIES;
81 simcall->host_get_properties.host = host;
82 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
83 simcall->host_get_properties.result = NULL;
84 SIMIX_simcall_push(simcall->issuer);
85 return simcall->host_get_properties.result;
89 * \ingroup simix_host_management
90 * \brief Returns the speed of the processor.
92 * The speed returned does not take into account the current load on the machine.
93 * \param host A SIMIX host
94 * \return The speed of this host (in Mflop/s)
96 double simcall_host_get_speed(smx_host_t host)
98 smx_simcall_t simcall = SIMIX_simcall_mine();
100 simcall->call = SIMCALL_HOST_GET_SPEED;
101 simcall->host_get_speed.host = host;
102 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
103 simcall->host_get_speed.result = 0.0;
104 SIMIX_simcall_push(simcall->issuer);
105 return simcall->host_get_speed.result;
109 * \ingroup simix_host_management
110 * \brief Returns the available speed of the processor.
112 * \return Speed currently available (in Mflop/s)
114 double simcall_host_get_available_speed(smx_host_t host)
116 smx_simcall_t simcall = SIMIX_simcall_mine();
118 simcall->call = SIMCALL_HOST_GET_AVAILABLE_SPEED;
119 simcall->host_get_available_speed.host = host;
120 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
121 simcall->host_get_available_speed.result = 0.0;
122 SIMIX_simcall_push(simcall->issuer);
123 return simcall->host_get_available_speed.result;
127 * \ingroup simix_host_management
128 * \brief Returns the state of a host.
130 * Two states are possible: 1 if the host is active or 0 if it has crashed.
131 * \param host A SIMIX host
132 * \return 1 if the host is available, 0 otherwise
134 int simcall_host_get_state(smx_host_t host)
136 smx_simcall_t simcall = SIMIX_simcall_mine();
138 simcall->call = SIMCALL_HOST_GET_STATE;
139 simcall->host_get_state.host = host;
140 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
141 simcall->host_get_state.result = -1;
142 SIMIX_simcall_push(simcall->issuer);
143 return simcall->host_get_state.result;
147 * \ingroup simix_host_management
148 * \brief Returns the user data associated to a host.
150 * \param host SIMIX host
151 * \return the user data of this host
153 void* simcall_host_get_data(smx_host_t host)
155 smx_simcall_t simcall = SIMIX_simcall_mine();
157 simcall->call = SIMCALL_HOST_GET_DATA;
158 simcall->host_get_data.host = host;
159 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
160 simcall->host_get_data.result = NULL;
161 SIMIX_simcall_push(simcall->issuer);
162 return simcall->host_get_data.result;
166 * \ingroup simix_host_management
167 * \brief Sets the user data associated to a host.
169 * The host must not have previous user data associated to it.
170 * \param host A SIMIX host
171 * \param data The user data to set
173 void simcall_host_set_data(smx_host_t host, void *data)
175 smx_simcall_t simcall = SIMIX_simcall_mine();
177 simcall->call = SIMCALL_HOST_SET_DATA;
178 simcall->host_set_data.host = host;
179 simcall->host_set_data.data = data;
180 SIMIX_simcall_push(simcall->issuer);
184 * \ingroup simix_host_management
185 * \brief Creates an action that executes some computation of an host.
187 * This function creates a SURF action and allocates the data necessary
188 * to create the SIMIX action. It can raise a host_error exception if the host crashed.
190 * \param name Name of the execution action to create
191 * \param host SIMIX host where the action will be executed
192 * \param computation_amount amount Computation amount (in bytes)
193 * \param priority computation priority
194 * \return A new SIMIX execution action
196 smx_action_t simcall_host_execute(const char *name, smx_host_t host,
197 double computation_amount,
200 /* checking for infinite values */
201 xbt_assert(isfinite(computation_amount), "computation_amount is not finite!");
202 xbt_assert(isfinite(priority), "priority is not finite!");
204 smx_simcall_t simcall = SIMIX_simcall_mine();
206 simcall->call = SIMCALL_HOST_EXECUTE;
207 simcall->host_execute.name = name;
208 simcall->host_execute.host = host;
209 simcall->host_execute.computation_amount = computation_amount;
210 simcall->host_execute.priority = priority;
211 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
212 simcall->host_execute.result = NULL;
213 SIMIX_simcall_push(simcall->issuer);
214 return simcall->host_execute.result;
218 * \ingroup simix_host_management
219 * \brief Creates an action that may involve parallel computation on
220 * several hosts and communication between them.
222 * \param name Name of the execution action to create
223 * \param host_nb Number of hosts where the action will be executed
224 * \param host_list Array (of size host_nb) of hosts where the action will be executed
225 * \param computation_amount Array (of size host_nb) of computation amount of hosts (in bytes)
226 * \param communication_amount Array (of size host_nb * host_nb) representing the communication
227 * amount between each pair of hosts
228 * \param amount the SURF action amount
229 * \param rate the SURF action rate
230 * \return A new SIMIX execution action
232 smx_action_t simcall_host_parallel_execute(const char *name,
234 smx_host_t *host_list,
235 double *computation_amount,
236 double *communication_amount,
241 /* checking for infinite values */
242 for (i = 0 ; i < host_nb ; ++i) {
243 xbt_assert(isfinite(computation_amount[i]), "computation_amount[%d] is not finite!", i);
244 for (j = 0 ; j < host_nb ; ++j) {
245 xbt_assert(isfinite(communication_amount[i + host_nb * j]),
246 "communication_amount[%d+%d*%d] is not finite!", i, host_nb, j);
250 xbt_assert(isfinite(amount), "amount is not finite!");
251 xbt_assert(isfinite(rate), "rate is not finite!");
253 smx_simcall_t simcall = SIMIX_simcall_mine();
255 simcall->call = SIMCALL_HOST_PARALLEL_EXECUTE;
256 simcall->host_parallel_execute.name = name;
257 simcall->host_parallel_execute.host_nb = host_nb;
258 simcall->host_parallel_execute.host_list = host_list;
259 simcall->host_parallel_execute.computation_amount = computation_amount;
260 simcall->host_parallel_execute.communication_amount = communication_amount;
261 simcall->host_parallel_execute.amount = amount;
262 simcall->host_parallel_execute.rate = rate;
263 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
264 simcall->host_parallel_execute.result = NULL;
265 SIMIX_simcall_push(simcall->issuer);
266 return simcall->host_parallel_execute.result;
270 * \ingroup simix_host_management
271 * \brief Destroys an execution action.
273 * Destroys an action, freing its memory. This function cannot be called if there are a conditional waiting for it.
274 * \param execution The execution action to destroy
276 void simcall_host_execution_destroy(smx_action_t execution)
278 smx_simcall_t simcall = SIMIX_simcall_mine();
280 simcall->call = SIMCALL_HOST_EXECUTION_DESTROY;
281 simcall->host_execution_destroy.execution = execution;
282 SIMIX_simcall_push(simcall->issuer);
286 * \ingroup simix_host_management
287 * \brief Cancels an execution action.
289 * This functions stops the execution. It calls a surf function.
290 * \param execution The execution action to cancel
292 void simcall_host_execution_cancel(smx_action_t execution)
294 smx_simcall_t simcall = SIMIX_simcall_mine();
296 simcall->call = SIMCALL_HOST_EXECUTION_CANCEL;
297 simcall->host_execution_cancel.execution = execution;
298 SIMIX_simcall_push(simcall->issuer);
302 * \ingroup simix_host_management
303 * \brief Returns how much of an execution action remains to be done.
305 * \param execution The execution action
306 * \return The remaining amount
308 double simcall_host_execution_get_remains(smx_action_t execution)
310 smx_simcall_t simcall = SIMIX_simcall_mine();
312 simcall->call = SIMCALL_HOST_EXECUTION_GET_REMAINS;
313 simcall->host_execution_get_remains.execution = execution;
314 if(MC_IS_ENABLED) /* Initializeialize result to a default value for snapshot comparison done during simcall */
315 simcall->host_execution_get_remains.result = 0.0;
316 SIMIX_simcall_push(simcall->issuer);
317 return simcall->host_execution_get_remains.result;
321 * \ingroup simix_host_management
322 * \brief Returns the state of an execution action.
324 * \param execution The execution action
327 e_smx_state_t simcall_host_execution_get_state(smx_action_t execution)
329 smx_simcall_t simcall = SIMIX_simcall_mine();
331 simcall->call = SIMCALL_HOST_EXECUTION_GET_STATE;
332 simcall->host_execution_get_state.execution = execution;
333 simcall->host_execution_get_state.result = -1;
334 SIMIX_simcall_push(simcall->issuer);
335 return simcall->host_execution_get_state.result;
339 * \ingroup simix_host_management
340 * \brief Changes the priority of an execution action.
342 * This functions changes the priority only. It calls a surf function.
343 * \param execution The execution action
344 * \param priority The new priority
346 void simcall_host_execution_set_priority(smx_action_t execution, double priority)
348 /* checking for infinite values */
349 xbt_assert(isfinite(priority), "priority is not finite!");
351 smx_simcall_t simcall = SIMIX_simcall_mine();
353 simcall->call = SIMCALL_HOST_EXECUTION_SET_PRIORITY;
354 simcall->host_execution_set_priority.execution = execution;
355 simcall->host_execution_set_priority.priority = priority;
356 SIMIX_simcall_push(simcall->issuer);
360 * \ingroup simix_host_management
361 * \brief Waits for the completion of an execution action and destroy it.
363 * \param execution The execution action
365 e_smx_state_t simcall_host_execution_wait(smx_action_t execution)
367 smx_simcall_t simcall = SIMIX_simcall_mine();
369 simcall->call = SIMCALL_HOST_EXECUTION_WAIT;
370 simcall->host_execution_wait.execution = execution;
371 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
372 simcall->host_execution_wait.result = -1;
373 SIMIX_simcall_push(simcall->issuer);
374 return simcall->host_execution_wait.result;
378 * \ingroup simix_process_management
379 * \brief Creates and runs a new SIMIX process.
381 * The structure and the corresponding thread are created and put in the list of ready processes.
383 * \param process the process created will be stored in this pointer
384 * \param name a name for the process. It is for user-level information and can be NULL.
385 * \param code the main function of the process
386 * \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.
387 * It can be retrieved with the function \ref simcall_process_get_data.
388 * \param hostname name of the host where the new agent is executed.
389 * \param kill_time time when the process is killed
390 * \param argc first argument passed to \a code
391 * \param argv second argument passed to \a code
392 * \param properties the properties of the process
393 * \param auto_restart either it is autorestarting or not.
395 void simcall_process_create(smx_process_t *process, const char *name,
396 xbt_main_func_t code,
398 const char *hostname,
400 int argc, char **argv,
401 xbt_dict_t properties,
404 smx_simcall_t simcall = SIMIX_simcall_mine();
406 simcall->call = SIMCALL_PROCESS_CREATE;
407 simcall->process_create.process = process;
408 simcall->process_create.name = name;
409 simcall->process_create.code = code;
410 simcall->process_create.data = data;
411 simcall->process_create.hostname = hostname;
412 simcall->process_create.kill_time = kill_time;
413 simcall->process_create.argc = argc;
414 simcall->process_create.argv = argv;
415 simcall->process_create.properties = properties;
416 simcall->process_create.auto_restart = auto_restart;
417 SIMIX_simcall_push(simcall->issuer);
421 * \ingroup simix_process_management
422 * \brief Kills a SIMIX process.
424 * This function simply kills a process.
426 * \param process poor victim
428 void simcall_process_kill(smx_process_t process)
430 smx_simcall_t simcall = SIMIX_simcall_mine();
432 simcall->call = SIMCALL_PROCESS_KILL;
433 simcall->process_kill.process = process;
434 SIMIX_simcall_push(simcall->issuer);
438 * \ingroup simix_process_management
439 * \brief Kills all SIMIX processes.
441 void simcall_process_killall(void)
443 smx_simcall_t simcall = SIMIX_simcall_mine();
445 simcall->call = SIMCALL_PROCESS_KILLALL;
446 SIMIX_simcall_push(simcall->issuer);
450 * \ingroup simix_process_management
451 * \brief Cleans up a SIMIX process.
452 * \param process poor victim (must have already been killed)
454 void simcall_process_cleanup(smx_process_t process)
456 smx_simcall_t simcall = SIMIX_simcall_mine();
458 simcall->call = SIMCALL_PROCESS_CLEANUP;
459 simcall->process_cleanup.process = process;
460 SIMIX_simcall_push(simcall->issuer);
464 * \ingroup simix_process_management
465 * \brief Migrates an agent to another location.
467 * This function changes the value of the host on which \a process is running.
469 * \param process the process to migrate
470 * \param dest name of the new host
472 void simcall_process_change_host(smx_process_t process, smx_host_t dest)
474 smx_simcall_t simcall = SIMIX_simcall_mine();
476 simcall->call = SIMCALL_PROCESS_CHANGE_HOST;
477 simcall->process_change_host.process = process;
478 simcall->process_change_host.dest = dest;
479 SIMIX_simcall_push(simcall->issuer);
483 * \ingroup simix_process_management
484 * \brief Suspends a process.
486 * This function suspends the process by suspending the action
487 * it was waiting for completion.
489 * \param process a SIMIX process
491 void simcall_process_suspend(smx_process_t process)
493 xbt_assert(process, "Invalid parameters");
495 smx_simcall_t simcall = SIMIX_simcall_mine();
497 simcall->call = SIMCALL_PROCESS_SUSPEND;
498 simcall->process_suspend.process = process;
499 SIMIX_simcall_push(simcall->issuer);
503 * \ingroup simix_process_management
504 * \brief Resumes a suspended process.
506 * This function resumes a suspended process by resuming the action
507 * it was waiting for completion.
509 * \param process a SIMIX process
511 void simcall_process_resume(smx_process_t process)
513 smx_simcall_t simcall = SIMIX_simcall_mine();
515 simcall->call = SIMCALL_PROCESS_RESUME;
516 simcall->process_resume.process = process;
517 SIMIX_simcall_push(simcall->issuer);
521 * \ingroup simix_process_management
522 * \brief Returns the amount of SIMIX processes in the system
524 * Maestro internal process is not counted, only user code processes are
526 int simcall_process_count(void)
528 smx_simcall_t simcall = SIMIX_simcall_mine();
530 simcall->call = SIMCALL_PROCESS_COUNT;
531 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
532 simcall->process_count.result = -1;
533 SIMIX_simcall_push(simcall->issuer);
534 return simcall->process_count.result;
538 * \ingroup simix_process_management
539 * \brief Return the user data of a #smx_process_t.
540 * \param process a SIMIX process
541 * \return the user data of this process
543 void* simcall_process_get_data(smx_process_t process)
545 if (process == SIMIX_process_self()) {
546 /* avoid a simcall if this function is called by the process itself */
547 return SIMIX_process_get_data(process);
550 smx_simcall_t simcall = SIMIX_simcall_mine();
552 simcall->call = SIMCALL_PROCESS_GET_DATA;
553 simcall->process_get_data.process = process;
554 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
555 simcall->process_get_data.result = NULL;
556 SIMIX_simcall_push(simcall->issuer);
557 return simcall->process_get_data.result;
561 * \ingroup simix_process_management
562 * \brief Set the user data of a #smx_process_t.
564 * This functions sets the user data associated to \a process.
565 * \param process SIMIX process
566 * \param data User data
568 void simcall_process_set_data(smx_process_t process, void *data)
570 if (process == SIMIX_process_self()) {
571 /* avoid a simcall if this function is called by the process itself */
572 SIMIX_process_self_set_data(process, data);
576 smx_simcall_t simcall = SIMIX_simcall_mine();
578 simcall->call = SIMCALL_PROCESS_SET_DATA;
579 simcall->process_set_data.process = process;
580 simcall->process_set_data.data = data;
581 SIMIX_simcall_push(simcall->issuer);
586 * \ingroup simix_process_management
587 * \brief Set the kill time of a process.
588 * \param process a process
589 * \param kill_time a double
591 void simcall_process_set_kill_time(smx_process_t process, double kill_time)
594 if (kill_time > SIMIX_get_clock()) {
595 if (simix_global->kill_process_function) {
596 XBT_DEBUG("Set kill time %f for process %s(%s)",kill_time, process->name,
597 process->smx_host->name);
598 SIMIX_timer_set(kill_time, simix_global->kill_process_function, process);
604 * \ingroup simix_process_management
605 * \brief Return the location on which an agent is running.
607 * This functions returns the smx_host_t corresponding to the location on which
608 * \a process is running.
609 * \param process SIMIX process
612 smx_host_t simcall_process_get_host(smx_process_t process)
614 smx_simcall_t simcall = SIMIX_simcall_mine();
616 simcall->call = SIMCALL_PROCESS_GET_HOST;
617 simcall->process_get_host.process = process;
618 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
619 simcall->process_get_host.result = NULL;
620 SIMIX_simcall_push(simcall->issuer);
621 return simcall->process_get_host.result;
625 * \ingroup simix_process_management
626 * \brief Return the name of an agent.
628 * This functions checks whether \a process is a valid pointer or not and return its name.
629 * \param process SIMIX process
630 * \return The process name
632 const char* simcall_process_get_name(smx_process_t process)
634 if (process == SIMIX_process_self()) {
635 /* avoid a simcall if this function is called by the process itself */
636 return process->name;
639 smx_simcall_t simcall = SIMIX_simcall_mine();
641 simcall->call = SIMCALL_PROCESS_GET_NAME;
642 simcall->process_get_name.process = process;
643 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
644 simcall->process_get_name.result = NULL;
645 SIMIX_simcall_push(simcall->issuer);
646 return simcall->process_get_name.result;
650 * \ingroup simix_process_management
651 * \brief Returns true if the process is suspended .
653 * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
654 * \param process SIMIX process
655 * \return 1, if the process is suspended, else 0.
657 int simcall_process_is_suspended(smx_process_t process)
659 smx_simcall_t simcall = SIMIX_simcall_mine();
661 simcall->call = SIMCALL_PROCESS_IS_SUSPENDED;
662 simcall->process_is_suspended.process = process;
663 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
664 simcall->process_is_suspended.result = -1;
665 SIMIX_simcall_push(simcall->issuer);
666 return simcall->process_is_suspended.result;
670 * \ingroup simix_process_management
671 * \brief Return the properties
673 * This functions returns the properties associated with this process
675 xbt_dict_t simcall_process_get_properties(smx_process_t process)
677 smx_simcall_t simcall = SIMIX_simcall_mine();
679 simcall->call = SIMCALL_PROCESS_GET_PROPERTIES;
680 simcall->process_get_properties.process = process;
681 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
682 simcall->process_get_properties.result = NULL;
683 SIMIX_simcall_push(simcall->issuer);
684 return simcall->process_get_properties.result;
687 * \ingroup simix_process_management
688 * \brief Add an on_exit function
689 * Add an on_exit function which will be executed when the process exits/is killed.
691 XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
693 smx_simcall_t simcall = SIMIX_simcall_mine();
695 simcall->call = SIMCALL_PROCESS_ON_EXIT;
696 simcall->process_on_exit.process = process;
697 simcall->process_on_exit.fun = fun;
698 simcall->process_on_exit.data = data;
700 SIMIX_simcall_push(simcall->issuer);
703 * \ingroup simix_process_management
704 * \brief Sets the process to be auto-restarted or not by SIMIX when its host comes back up.
705 * Will restart the process when the host comes back up if auto_restart is set to 1.
708 XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart)
710 smx_simcall_t simcall = SIMIX_simcall_mine();
712 simcall->call = SIMCALL_PROCESS_AUTO_RESTART_SET;
713 simcall->process_auto_restart.process = process;
714 simcall->process_auto_restart.auto_restart = auto_restart;
716 SIMIX_simcall_push(simcall->issuer);
719 * \ingroup simix_process_management
720 * \brief Restarts the process, killing it and starting it again from scratch.
722 XBT_PUBLIC(smx_process_t) simcall_process_restart(smx_process_t process)
724 smx_simcall_t simcall = SIMIX_simcall_mine();
726 simcall->call = SIMCALL_PROCESS_RESTART;
727 simcall->process_restart.process = process;
728 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
729 simcall->process_restart.result = NULL;
731 SIMIX_simcall_push(simcall->issuer);
733 return simcall->process_restart.result;
736 * \ingroup simix_process_management
737 * \brief Creates a new sleep SIMIX action.
739 * This function creates a SURF action and allocates the data necessary
740 * to create the SIMIX action. It can raise a host_error exception if the
741 * host crashed. The default SIMIX name of the action is "sleep".
743 * \param duration Time duration of the sleep.
744 * \return A result telling whether the sleep was successful
746 e_smx_state_t simcall_process_sleep(double duration)
748 /* checking for infinite values */
749 xbt_assert(isfinite(duration), "duration is not finite!");
751 smx_simcall_t simcall = SIMIX_simcall_mine();
753 simcall->call = SIMCALL_PROCESS_SLEEP;
754 simcall->process_sleep.duration = duration;
755 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
756 simcall->process_sleep.result = -1;
757 SIMIX_simcall_push(simcall->issuer);
758 return simcall->process_sleep.result;
762 * \ingroup simix_rdv_management
763 * \brief Creates a new rendez-vous point
764 * \param name The name of the rendez-vous point
765 * \return The created rendez-vous point
767 smx_rdv_t simcall_rdv_create(const char *name)
769 smx_simcall_t simcall = SIMIX_simcall_mine();
771 simcall->call = SIMCALL_RDV_CREATE;
772 simcall->rdv_create.name = name;
773 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
774 simcall->rdv_create.result = NULL;
776 SIMIX_simcall_push(simcall->issuer);
777 return simcall->rdv_create.result;
782 * \ingroup simix_rdv_management
783 * \brief Destroy a rendez-vous point
784 * \param rdv The rendez-vous point to destroy
786 void simcall_rdv_destroy(smx_rdv_t rdv)
788 smx_simcall_t simcall = SIMIX_simcall_mine();
790 simcall->call = SIMCALL_RDV_DESTROY;
791 simcall->rdv_destroy.rdv = rdv;
793 SIMIX_simcall_push(simcall->issuer);
796 * \ingroup simix_rdv_management
797 * \brief Returns a rendez-vous point knowing its name
799 smx_rdv_t simcall_rdv_get_by_name(const char *name)
801 xbt_assert(name != NULL, "Invalid parameter for simcall_rdv_get_by_name (name is NULL)");
803 /* FIXME: this is a horrible lost of performance, so we hack it out by
804 * skipping the simcall (for now). It works in parallel, it won't work on
805 * distributed but probably we will change MSG for that. */
808 smx_simcall_t simcall = simcall_mine();
809 simcall->call = SIMCALL_RDV_GEY_BY_NAME;
810 simcall->rdv_get_by_name.name = name;
811 SIMIX_simcall_push(simcall->issuer);
812 return simcall->rdv_get_by_name.result;*/
814 return SIMIX_rdv_get_by_name(name);
818 * \ingroup simix_rdv_management
819 * \brief Counts the number of communication actions of a given host pending
820 * on a rendez-vous point.
821 * \param rdv The rendez-vous point
822 * \param host The host to be counted
823 * \return The number of comm actions pending in the rdv
825 int simcall_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
827 smx_simcall_t simcall = SIMIX_simcall_mine();
829 simcall->call = SIMCALL_RDV_COMM_COUNT_BY_HOST;
830 simcall->rdv_comm_count_by_host.rdv = rdv;
831 simcall->rdv_comm_count_by_host.host = host;
832 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
833 simcall->rdv_comm_count_by_host.result = -1;
835 SIMIX_simcall_push(simcall->issuer);
836 return simcall->rdv_comm_count_by_host.result;
840 * \ingroup simix_rdv_management
841 * \brief returns the communication at the head of the rendez-vous
842 * \param rdv The rendez-vous point
843 * \return The communication or NULL if empty
845 smx_action_t simcall_rdv_get_head(smx_rdv_t rdv)
847 smx_simcall_t simcall = SIMIX_simcall_mine();
849 simcall->call = SIMCALL_RDV_GET_HEAD;
850 simcall->rdv_get_head.rdv = rdv;
851 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
852 simcall->rdv_get_head.result = NULL;
854 SIMIX_simcall_push(simcall->issuer);
855 return simcall->rdv_get_head.result;
858 void simcall_rdv_set_receiver(smx_rdv_t rdv , smx_process_t process)
860 smx_simcall_t simcall = SIMIX_simcall_mine();
862 simcall->call = SIMCALL_RDV_SET_RECV;
863 simcall->rdv_set_rcv_proc.rdv = rdv;
864 simcall->rdv_set_rcv_proc.receiver = process;
866 SIMIX_simcall_push(simcall->issuer);
869 smx_process_t simcall_rdv_get_receiver(smx_rdv_t rdv)
871 smx_simcall_t simcall = SIMIX_simcall_mine();
873 simcall->call = SIMCALL_RDV_GET_RECV;
874 simcall->rdv_get_rcv_proc.rdv = rdv;
875 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
876 simcall->rdv_get_rcv_proc.result = NULL;
878 SIMIX_simcall_push(simcall->issuer);
879 return simcall->rdv_get_rcv_proc.result;
883 * \ingroup simix_comm_management
885 void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
886 void *src_buff, size_t src_buff_size,
887 int (*match_fun)(void *, void *, smx_action_t), void *data,
890 /* checking for infinite values */
891 xbt_assert(isfinite(task_size), "task_size is not finite!");
892 xbt_assert(isfinite(rate), "rate is not finite!");
893 xbt_assert(isfinite(timeout), "timeout is not finite!");
895 xbt_assert(rdv, "No rendez-vous point defined for send");
898 /* the model-checker wants two separate simcalls */
899 smx_action_t comm = simcall_comm_isend(rdv, task_size, rate,
900 src_buff, src_buff_size, match_fun, NULL, data, 0);
901 simcall_comm_wait(comm, timeout);
904 smx_simcall_t simcall = SIMIX_simcall_mine();
906 simcall->call = SIMCALL_COMM_SEND;
907 simcall->comm_send.rdv = rdv;
908 simcall->comm_send.task_size = task_size;
909 simcall->comm_send.rate = rate;
910 simcall->comm_send.src_buff = src_buff;
911 simcall->comm_send.src_buff_size = src_buff_size;
912 simcall->comm_send.match_fun = match_fun;
913 simcall->comm_send.data = data;
914 simcall->comm_send.timeout = timeout;
916 SIMIX_simcall_push(simcall->issuer);
920 * \ingroup simix_comm_management
922 smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
923 void *src_buff, size_t src_buff_size,
924 int (*match_fun)(void *, void *, smx_action_t),
925 void (*clean_fun)(void *),
929 /* checking for infinite values */
930 xbt_assert(isfinite(task_size), "task_size is not finite!");
931 xbt_assert(isfinite(rate), "rate is not finite!");
933 xbt_assert(rdv, "No rendez-vous point defined for isend");
935 smx_simcall_t simcall = SIMIX_simcall_mine();
937 simcall->call = SIMCALL_COMM_ISEND;
938 simcall->comm_isend.rdv = rdv;
939 simcall->comm_isend.task_size = task_size;
940 simcall->comm_isend.rate = rate;
941 simcall->comm_isend.src_buff = src_buff;
942 simcall->comm_isend.src_buff_size = src_buff_size;
943 simcall->comm_isend.match_fun = match_fun;
944 simcall->comm_isend.clean_fun = clean_fun;
945 simcall->comm_isend.data = data;
946 simcall->comm_isend.detached = detached;
947 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
948 simcall->comm_isend.result = NULL;
950 SIMIX_simcall_push(simcall->issuer);
951 return simcall->comm_isend.result;
954 * \ingroup simix_comm_management
956 void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
957 int (*match_fun)(void *, void *, smx_action_t), void *data, double timeout)
959 xbt_assert(isfinite(timeout), "timeout is not finite!");
960 xbt_assert(rdv, "No rendez-vous point defined for recv");
963 /* the model-checker wants two separate simcalls */
964 smx_action_t comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
966 simcall_comm_wait(comm, timeout);
969 smx_simcall_t simcall = SIMIX_simcall_mine();
971 simcall->call = SIMCALL_COMM_RECV;
972 simcall->comm_recv.rdv = rdv;
973 simcall->comm_recv.dst_buff = dst_buff;
974 simcall->comm_recv.dst_buff_size = dst_buff_size;
975 simcall->comm_recv.match_fun = match_fun;
976 simcall->comm_recv.data = data;
977 simcall->comm_recv.timeout = timeout;
979 SIMIX_simcall_push(simcall->issuer);
983 * \ingroup simix_comm_management
985 smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
986 int (*match_fun)(void *, void *, smx_action_t), void *data)
988 xbt_assert(rdv, "No rendez-vous point defined for irecv");
990 smx_simcall_t simcall = SIMIX_simcall_mine();
992 simcall->call = SIMCALL_COMM_IRECV;
993 simcall->comm_irecv.rdv = rdv;
994 simcall->comm_irecv.dst_buff = dst_buff;
995 simcall->comm_irecv.dst_buff_size = dst_buff_size;
996 simcall->comm_irecv.match_fun = match_fun;
997 simcall->comm_irecv.data = data;
998 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
999 simcall->comm_irecv.result = NULL;
1001 SIMIX_simcall_push(simcall->issuer);
1002 return simcall->comm_irecv.result;
1004 void simcall_comm_destroy(smx_action_t comm)
1006 xbt_assert(comm, "Invalid parameter");
1008 /* FIXME remove this simcall type: comms are auto-destroyed now */
1011 smx_simcall_t simcall = simcall_mine();
1013 simcall->call = SIMCALL_COMM_DESTROY;
1014 simcall->comm_destroy.comm = comm;
1016 SIMIX_simcall_push(simcall->issuer);
1020 * \ingroup simix_comm_management
1022 void simcall_comm_cancel(smx_action_t comm)
1024 smx_simcall_t simcall = SIMIX_simcall_mine();
1026 simcall->call = SIMCALL_COMM_CANCEL;
1027 simcall->comm_cancel.comm = comm;
1029 SIMIX_simcall_push(simcall->issuer);
1032 * \ingroup simix_comm_management
1034 unsigned int simcall_comm_waitany(xbt_dynar_t comms)
1036 smx_simcall_t simcall = SIMIX_simcall_mine();
1038 simcall->call = SIMCALL_COMM_WAITANY;
1039 simcall->comm_waitany.comms = comms;
1040 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1041 simcall->comm_waitany.result = -1;
1043 SIMIX_simcall_push(simcall->issuer);
1044 return simcall->comm_waitany.result;
1047 * \ingroup simix_comm_management
1049 int simcall_comm_testany(xbt_dynar_t comms)
1051 smx_simcall_t simcall = SIMIX_simcall_mine();
1052 if (xbt_dynar_is_empty(comms))
1055 simcall->call = SIMCALL_COMM_TESTANY;
1056 simcall->comm_testany.comms = comms;
1057 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1058 simcall->comm_testany.result = -1;
1060 SIMIX_simcall_push(simcall->issuer);
1061 return simcall->comm_testany.result;
1064 * \ingroup simix_comm_management
1066 void simcall_comm_wait(smx_action_t comm, double timeout)
1068 xbt_assert(isfinite(timeout), "timeout is not finite!");
1070 smx_simcall_t simcall = SIMIX_simcall_mine();
1072 simcall->call = SIMCALL_COMM_WAIT;
1073 simcall->comm_wait.comm = comm;
1074 simcall->comm_wait.timeout = timeout;
1076 SIMIX_simcall_push(simcall->issuer);
1081 * \brief Set the category of an action.
1083 * This functions changes the category only. It calls a surf function.
1084 * \param execution The execution action
1085 * \param category The tracing category
1087 void simcall_set_category(smx_action_t action, const char *category)
1089 if (category == NULL) {
1093 smx_simcall_t simcall = SIMIX_simcall_mine();
1095 simcall->call = SIMCALL_SET_CATEGORY;
1096 simcall->set_category.action = action;
1097 simcall->set_category.category = category;
1099 SIMIX_simcall_push(simcall->issuer);
1103 * \ingroup simix_comm_management
1106 int simcall_comm_test(smx_action_t comm)
1108 smx_simcall_t simcall = SIMIX_simcall_mine();
1110 simcall->call = SIMCALL_COMM_TEST;
1111 simcall->comm_test.comm = comm;
1112 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1113 simcall->comm_test.result = -1;
1115 SIMIX_simcall_push(simcall->issuer);
1116 return simcall->comm_test.result;
1119 * \ingroup simix_comm_management
1122 double simcall_comm_get_remains(smx_action_t comm)
1124 smx_simcall_t simcall = SIMIX_simcall_mine();
1126 simcall->call = SIMCALL_COMM_GET_REMAINS;
1127 simcall->comm_get_remains.comm = comm;
1128 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1129 simcall->comm_get_remains.result = 0.0;
1131 SIMIX_simcall_push(simcall->issuer);
1132 return simcall->comm_get_remains.result;
1135 * \ingroup simix_comm_management
1138 e_smx_state_t simcall_comm_get_state(smx_action_t comm)
1140 smx_simcall_t simcall = SIMIX_simcall_mine();
1142 simcall->call = SIMCALL_COMM_GET_STATE;
1143 simcall->comm_get_state.comm = comm;
1144 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1145 simcall->comm_get_state.result = -1;
1147 SIMIX_simcall_push(simcall->issuer);
1148 return simcall->comm_get_state.result;
1151 * \ingroup simix_comm_management
1154 void *simcall_comm_get_src_data(smx_action_t comm)
1156 smx_simcall_t simcall = SIMIX_simcall_mine();
1158 simcall->call = SIMCALL_COMM_GET_SRC_DATA;
1159 simcall->comm_get_src_data.comm = comm;
1160 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1161 simcall->comm_get_src_data.result = NULL;
1163 SIMIX_simcall_push(simcall->issuer);
1164 return simcall->comm_get_src_data.result;
1167 * \ingroup simix_comm_management
1170 void *simcall_comm_get_dst_data(smx_action_t comm)
1172 smx_simcall_t simcall = SIMIX_simcall_mine();
1174 simcall->call = SIMCALL_COMM_GET_DST_DATA;
1175 simcall->comm_get_dst_data.comm = comm;
1176 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1177 simcall->comm_get_dst_data.result = NULL;
1179 SIMIX_simcall_push(simcall->issuer);
1180 return simcall->comm_get_dst_data.result;
1183 * \ingroup simix_comm_management
1186 smx_process_t simcall_comm_get_src_proc(smx_action_t comm)
1188 smx_simcall_t simcall = SIMIX_simcall_mine();
1190 simcall->call = SIMCALL_COMM_GET_SRC_PROC;
1191 simcall->comm_get_src_proc.comm = comm;
1192 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1193 simcall->comm_get_src_proc.result = NULL;
1195 SIMIX_simcall_push(simcall->issuer);
1196 return simcall->comm_get_src_proc.result;
1199 * \ingroup simix_comm_management
1202 smx_process_t simcall_comm_get_dst_proc(smx_action_t comm)
1204 smx_simcall_t simcall = SIMIX_simcall_mine();
1206 simcall->call = SIMCALL_COMM_GET_DST_PROC;
1207 simcall->comm_get_dst_proc.comm = comm;
1208 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1209 simcall->comm_get_dst_proc.result = NULL;
1211 SIMIX_simcall_push(simcall->issuer);
1212 return simcall->comm_get_dst_proc.result;
1215 #ifdef HAVE_LATENCY_BOUND_TRACKING
1216 int simcall_comm_is_latency_bounded(smx_action_t comm)
1218 smx_simcall_t simcall = SIMIX_simcall_mine();
1220 simcall->call = SIMCALL_COMM_IS_LATENCY_BOUNDED;
1221 simcall->comm_is_latency_bounded.comm = comm;
1222 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1223 simcall->comm_is_latency_bounded.result = -1;
1225 SIMIX_simcall_push(simcall->issuer);
1226 return simcall->comm_is_latency_bounded.result;
1230 * \ingroup simix_synchro_management
1233 smx_mutex_t simcall_mutex_init(void)
1236 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... :)
1239 smx_simcall_t simcall = SIMIX_simcall_mine();
1241 simcall->call = SIMCALL_MUTEX_INIT;
1242 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1243 simcall->mutex_init.result = NULL;
1245 SIMIX_simcall_push(simcall->issuer);
1246 return simcall->mutex_init.result;
1249 * \ingroup simix_synchro_management
1252 void simcall_mutex_destroy(smx_mutex_t mutex)
1254 smx_simcall_t simcall = SIMIX_simcall_mine();
1256 simcall->call = SIMCALL_MUTEX_DESTROY;
1257 simcall->mutex_destroy.mutex = mutex;
1259 SIMIX_simcall_push(simcall->issuer);
1262 * \ingroup simix_synchro_management
1265 void simcall_mutex_lock(smx_mutex_t mutex)
1267 smx_simcall_t simcall = SIMIX_simcall_mine();
1269 simcall->call = SIMCALL_MUTEX_LOCK;
1270 simcall->mutex_lock.mutex = mutex;
1272 SIMIX_simcall_push(simcall->issuer);
1275 * \ingroup simix_synchro_management
1278 int simcall_mutex_trylock(smx_mutex_t mutex)
1280 smx_simcall_t simcall = SIMIX_simcall_mine();
1282 simcall->call = SIMCALL_MUTEX_TRYLOCK;
1283 simcall->mutex_trylock.mutex = mutex;
1284 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1285 simcall->mutex_trylock.result = -1;
1287 SIMIX_simcall_push(simcall->issuer);
1288 return simcall->mutex_trylock.result;
1291 * \ingroup simix_synchro_management
1294 void simcall_mutex_unlock(smx_mutex_t mutex)
1296 smx_simcall_t simcall = SIMIX_simcall_mine();
1298 simcall->call = SIMCALL_MUTEX_UNLOCK;
1299 simcall->mutex_unlock.mutex = mutex;
1301 SIMIX_simcall_push(simcall->issuer);
1304 * \ingroup simix_synchro_management
1307 smx_cond_t simcall_cond_init(void)
1309 smx_simcall_t simcall = SIMIX_simcall_mine();
1311 simcall->call = SIMCALL_COND_INIT;
1312 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1313 simcall->cond_init.result = NULL;
1315 SIMIX_simcall_push(simcall->issuer);
1316 return simcall->cond_init.result;
1319 * \ingroup simix_synchro_management
1322 void simcall_cond_destroy(smx_cond_t cond)
1324 smx_simcall_t simcall = SIMIX_simcall_mine();
1326 simcall->call = SIMCALL_COND_DESTROY;
1327 simcall->cond_destroy.cond = cond;
1329 SIMIX_simcall_push(simcall->issuer);
1332 * \ingroup simix_synchro_management
1335 void simcall_cond_signal(smx_cond_t cond)
1337 smx_simcall_t simcall = SIMIX_simcall_mine();
1339 simcall->call = SIMCALL_COND_SIGNAL;
1340 simcall->cond_signal.cond = cond;
1342 SIMIX_simcall_push(simcall->issuer);
1345 * \ingroup simix_synchro_management
1348 void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
1350 smx_simcall_t simcall = SIMIX_simcall_mine();
1352 simcall->call = SIMCALL_COND_WAIT;
1353 simcall->cond_wait.cond = cond;
1354 simcall->cond_wait.mutex = mutex;
1356 SIMIX_simcall_push(simcall->issuer);
1359 * \ingroup simix_synchro_management
1362 void simcall_cond_wait_timeout(smx_cond_t cond,
1366 xbt_assert(isfinite(timeout), "timeout is not finite!");
1368 smx_simcall_t simcall = SIMIX_simcall_mine();
1370 simcall->call = SIMCALL_COND_WAIT_TIMEOUT;
1371 simcall->cond_wait_timeout.cond = cond;
1372 simcall->cond_wait_timeout.mutex = mutex;
1373 simcall->cond_wait_timeout.timeout = timeout;
1375 SIMIX_simcall_push(simcall->issuer);
1378 * \ingroup simix_synchro_management
1381 void simcall_cond_broadcast(smx_cond_t cond)
1383 smx_simcall_t simcall = SIMIX_simcall_mine();
1385 simcall->call = SIMCALL_COND_BROADCAST;
1386 simcall->cond_broadcast.cond = cond;
1388 SIMIX_simcall_push(simcall->issuer);
1391 * \ingroup simix_synchro_management
1394 smx_sem_t simcall_sem_init(int capacity)
1396 smx_simcall_t simcall = SIMIX_simcall_mine();
1398 simcall->call = SIMCALL_SEM_INIT;
1399 simcall->sem_init.capacity = capacity;
1400 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1401 simcall->sem_init.result = NULL;
1403 SIMIX_simcall_push(simcall->issuer);
1404 return simcall->sem_init.result;
1407 * \ingroup simix_synchro_management
1410 void simcall_sem_destroy(smx_sem_t sem)
1412 smx_simcall_t simcall = SIMIX_simcall_mine();
1414 simcall->call = SIMCALL_SEM_DESTROY;
1415 simcall->sem_destroy.sem = sem;
1417 SIMIX_simcall_push(simcall->issuer);
1420 * \ingroup simix_synchro_management
1423 void simcall_sem_release(smx_sem_t sem)
1425 smx_simcall_t simcall = SIMIX_simcall_mine();
1427 simcall->call = SIMCALL_SEM_RELEASE;
1428 simcall->sem_release.sem = sem;
1430 SIMIX_simcall_push(simcall->issuer);
1433 * \ingroup simix_synchro_management
1436 int simcall_sem_would_block(smx_sem_t sem)
1438 smx_simcall_t simcall = SIMIX_simcall_mine();
1440 simcall->call = SIMCALL_SEM_WOULD_BLOCK;
1441 simcall->sem_would_block.sem = sem;
1442 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1443 simcall->sem_would_block.result = -1;
1445 SIMIX_simcall_push(simcall->issuer);
1446 return simcall->sem_would_block.result;
1449 * \ingroup simix_synchro_management
1452 void simcall_sem_acquire(smx_sem_t sem)
1454 smx_simcall_t simcall = SIMIX_simcall_mine();
1456 simcall->call = SIMCALL_SEM_ACQUIRE;
1457 simcall->sem_acquire.sem = sem;
1459 SIMIX_simcall_push(simcall->issuer);
1462 * \ingroup simix_synchro_management
1465 void simcall_sem_acquire_timeout(smx_sem_t sem, double timeout)
1467 xbt_assert(isfinite(timeout), "timeout is not finite!");
1469 smx_simcall_t simcall = SIMIX_simcall_mine();
1471 simcall->call = SIMCALL_SEM_ACQUIRE_TIMEOUT;
1472 simcall->sem_acquire_timeout.sem = sem;
1473 simcall->sem_acquire_timeout.timeout = timeout;
1475 SIMIX_simcall_push(simcall->issuer);
1478 * \ingroup simix_synchro_management
1481 int simcall_sem_get_capacity(smx_sem_t sem)
1483 smx_simcall_t simcall = SIMIX_simcall_mine();
1485 simcall->call = SIMCALL_SEM_GET_CAPACITY;
1486 simcall->sem_get_capacity.sem = sem;
1487 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1488 simcall->sem_get_capacity.result = -1;
1490 SIMIX_simcall_push(simcall->issuer);
1491 return simcall->sem_get_capacity.result;
1494 * \ingroup simix_file_management
1497 double simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1499 smx_simcall_t simcall = SIMIX_simcall_mine();
1501 simcall->call = SIMCALL_FILE_READ;
1502 simcall->file_read.ptr = ptr;
1503 simcall->file_read.size = size;
1504 simcall->file_read.nmemb = nmemb;
1505 simcall->file_read.stream = stream;
1506 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1507 simcall->file_read.result = 0.0;
1508 SIMIX_simcall_push(simcall->issuer);
1510 return simcall->file_read.result;
1513 * \ingroup simix_file_management
1516 size_t simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
1518 smx_simcall_t simcall = SIMIX_simcall_mine();
1520 simcall->call = SIMCALL_FILE_WRITE;
1521 simcall->file_write.ptr = ptr;
1522 simcall->file_write.size = size;
1523 simcall->file_write.nmemb = nmemb;
1524 simcall->file_write.stream = stream;
1525 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1526 simcall->file_write.result = 0;
1527 SIMIX_simcall_push(simcall->issuer);
1529 return simcall->file_write.result;
1532 * \ingroup simix_file_management
1535 smx_file_t simcall_file_open(const char* mount, const char* path, const char* mode)
1537 smx_simcall_t simcall = SIMIX_simcall_mine();
1539 simcall->call = SIMCALL_FILE_OPEN;
1540 simcall->file_open.mount = mount;
1541 simcall->file_open.path = path;
1542 simcall->file_open.mode = mode;
1543 if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
1544 simcall->file_open.result = NULL;
1545 SIMIX_simcall_push(simcall->issuer);
1547 return simcall->file_open.result;
1550 * \ingroup simix_file_management
1553 int simcall_file_close(smx_file_t fp)
1555 smx_simcall_t simcall = SIMIX_simcall_mine();
1557 simcall->call = SIMCALL_FILE_CLOSE;
1558 simcall->file_close.fp = fp;
1559 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1560 simcall->file_close.result = -1;
1561 SIMIX_simcall_push(simcall->issuer);
1563 return simcall->file_close.result;
1566 * \ingroup simix_file_management
1569 int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
1571 smx_simcall_t simcall = SIMIX_simcall_mine();
1572 simcall->call = SIMCALL_FILE_STAT;
1573 simcall->file_stat.fd = fd;
1574 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1575 simcall->file_stat.result = -1;
1577 SIMIX_simcall_push(simcall->issuer);
1579 *buf = simcall->file_stat.buf;
1581 return simcall->file_stat.result;
1585 * \ingroup simix_file_management
1588 int simcall_file_unlink(smx_file_t fd)
1590 smx_simcall_t simcall = SIMIX_simcall_mine();
1591 simcall->call = SIMCALL_FILE_UNLINK;
1592 simcall->file_unlink.fd = fd;
1593 if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
1594 simcall->file_unlink.result = -1;
1596 SIMIX_simcall_push(simcall->issuer);
1598 return simcall->file_unlink.result;
1601 /* ************************************************************************** */
1603 /** @brief returns a printable string representing a simcall */
1604 const char *SIMIX_simcall_name(e_smx_simcall_t kind) {
1605 return simcall_names[kind];