to the process to run by SIMIX_process_kill if he is the issuer of the function, else he
will be added twice to the process_to_run dynar.
Add simcall_process_restart, SIMIX_process_restart and MSG_process_restart, which restarts
a process.
XBT_PUBLIC(void) MSG_process_on_exit(int_f_pvoid_t fun, void *data);
XBT_PUBLIC(void) MSG_process_auto_restart_set(msg_process_t process, int auto_restart);
+XBT_PUBLIC(void) MSG_process_restart(msg_process_t process);
+
/************************** Task handling ************************************/
XBT_PUBLIC(msg_task_t) MSG_task_create(const char *name,
double compute_duration,
/* Process creation/destruction callbacks */
typedef void (*void_pfn_smxprocess_t) (smx_process_t);
-
-/* for function autorestart */
+/* Process kill */
+typedef void (*void_pfn_smxprocess_t_smxprocess_t) (smx_process_t, smx_process_t);
+/* for auto-restart function */
typedef void (*void_pfn_smxhost_t) (smx_host_t);
/* The following function pointer types describe the interface that any context
XBT_PUBLIC(void) SIMIX_function_register_process_cleanup(void_pfn_smxprocess_t function);
XBT_PUBLIC(void) SIMIX_function_register_process_create(smx_creation_func_t function);
-XBT_PUBLIC(void) SIMIX_function_register_process_kill(void_pfn_smxprocess_t function);
+XBT_PUBLIC(void) SIMIX_function_register_process_kill(void_pfn_smxprocess_t_smxprocess_t function);
/* Simulation execution */
XBT_PUBLIC(void) SIMIX_run(void);
XBT_PUBLIC(void) simcall_process_set_kill_time(smx_process_t process, double kill_time);
XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data);
XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart);
+XBT_PUBLIC(void) simcall_process_restart(smx_process_t process);
/* Sleep control */
XBT_PUBLIC(e_smx_state_t) simcall_process_sleep(double duration);
SIMIX_function_register_process_create(MSG_process_create_from_SIMIX);
SIMIX_function_register_process_cleanup(MSG_process_cleanup_from_SIMIX);
- SIMIX_function_register_process_kill(MSG_process_kill);
}
#ifdef HAVE_TRACING
TRACE_start();
#ifdef HAVE_TRACING
TRACE_msg_process_end(smx_proc);
#endif
-
// free the data if a function was provided
if (msg_proc->data && msg_global->process_data_cleanup) {
msg_global->process_data_cleanup(msg_proc->data);
XBT_PUBLIC(void) MSG_process_auto_restart_set(msg_process_t process, int auto_restart) {
simcall_process_auto_restart_set(process,auto_restart);
}
+/*
+ * \ingroup m_process_management
+ * \brief Restarts a process from the beginning.
+ */
+XBT_PUBLIC(void) MSG_process_restart(msg_process_t process) {
+ simcall_process_restart(process);
+}
void smx_ctx_base_free(smx_context_t context)
{
int i;
-
if (context) {
/* free argv */
*
* \param function Kill process function
*/
-XBT_INLINE void SIMIX_function_register_process_kill(void_pfn_smxprocess_t
+XBT_INLINE void SIMIX_function_register_process_kill(void_pfn_smxprocess_t_smxprocess_t
function)
{
simix_global->kill_process_function = function;
smx_process_t maestro_process;
xbt_dict_t registered_functions;
smx_creation_func_t create_process_function;
- void_pfn_smxprocess_t kill_process_function;
+ void_pfn_smxprocess_t_smxprocess_t kill_process_function;
void_pfn_smxprocess_t cleanup_process_function;
xbt_mallocator_t action_mallocator;
void_pfn_smxhost_t autorestart;
*process = xbt_new0(s_smx_process_t, 1);
xbt_assert(((code != NULL) && (host != NULL)), "Invalid parameters");
-
/* Process data */
(*process)->pid = simix_process_maxpid++;
(*process)->name = xbt_strdup(name);
* or directly for SIMIX internal purposes.
*
* \param process poor victim
+ * \param issuer the process which has sent the PROCESS_KILL. Important to not schedule twice the same process.
*/
-void SIMIX_process_kill(smx_process_t process) {
+void SIMIX_process_kill(smx_process_t process, smx_process_t issuer) {
XBT_DEBUG("Killing process %s on %s", process->name, process->smx_host->name);
break;
}
}
- if(!xbt_dynar_member(simix_global->process_to_run, &(process)))
+ if(!xbt_dynar_member(simix_global->process_to_run, &(process)) && process != issuer) {
xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
+ }
+
}
/**
while ((p = xbt_swag_extract(simix_global->process_list))) {
if (p != issuer) {
- SIMIX_process_kill(p);
+ SIMIX_process_kill(p,issuer);
}
}
void SIMIX_process_auto_restart_set(smx_process_t process, int auto_restart) {
process->auto_restart = auto_restart;
}
+/**
+ * \brief Restart a process.
+ * Restart a process, starting it again from the beginning.
+ */
+void SIMIX_process_restart(smx_process_t process, smx_process_t issuer) {
+ XBT_DEBUG("Restarting process %s on %s", process->name, process->smx_host->name);
+ //retrieve the arguments of the old process
+ //FIXME: Factorise this with SIMIX_host_add_auto_restart_process ?
+ s_smx_process_arg_t arg;
+ arg.code = process->code;
+ arg.hostname = process->smx_host->name;
+ arg.kill_time = process->kill_time;
+ arg.argc = process->argc;
+ arg.data = process->data;
+ int i;
+ arg.argv = xbt_new(char*,process->argc + 1);
+ for (i = 0; i < arg.argc; i++) {
+ arg.argv[i] = xbt_strdup(process->argv[i]);
+ }
+ arg.argv[process->argc] = NULL;
+ arg.properties = NULL;
+ arg.auto_restart = process->auto_restart;
+ //kill the old process
+ SIMIX_process_kill(process,issuer);
+ //start the new process
+ smx_process_t new_process;
+ if (simix_global->create_process_function) {
+ simix_global->create_process_function(&new_process,
+ arg.argv[0],
+ arg.code,
+ arg.data,
+ arg.hostname,
+ arg.kill_time,
+ arg.argc,
+ arg.argv,
+ arg.properties,
+ arg.auto_restart);
+ }
+ else {
+ simcall_process_create(&new_process,
+ arg.argv[0],
+ arg.code,
+ arg.data,
+ arg.hostname,
+ arg.kill_time,
+ arg.argc,
+ arg.argv,
+ arg.properties,
+ arg.auto_restart);
+
+ }
+
+}
xbt_dict_t properties,
int auto_restart);
void SIMIX_process_runall(void);
-void SIMIX_process_kill(smx_process_t process);
+void SIMIX_process_kill(smx_process_t process, smx_process_t issuer);
void SIMIX_process_killall(smx_process_t issuer);
smx_process_t SIMIX_process_create_from_wrapper(smx_process_arg_t args);
void SIMIX_create_maestro_process(void);
void SIMIX_process_sleep_resume(smx_action_t action);
void SIMIX_process_sleep_destroy(smx_action_t action);
void SIMIX_process_auto_restart_set(smx_process_t process, int auto_restart);
-
+void SIMIX_process_restart(smx_process_t process, smx_process_t issuer);
#endif
break;
case SIMCALL_PROCESS_KILL:
- SIMIX_process_kill(simcall->process_kill.process);
+ SIMIX_process_kill(simcall->process_kill.process,simcall->issuer);
SIMIX_simcall_answer(simcall);
break;
case SIMCALL_PROCESS_CHANGE_HOST:
SIMIX_pre_process_change_host(
- simcall->process_change_host.process,
- simcall->process_change_host.dest);
+ simcall->process_change_host.process,
+ simcall->process_change_host.dest);
SIMIX_simcall_answer(simcall);
break;
simcall->process_on_exit.data);
SIMIX_simcall_answer(simcall);
break;
+ case SIMCALL_PROCESS_RESTART:
+ SIMIX_process_restart(simcall->process_restart.process, simcall->issuer);
+ SIMIX_simcall_answer(simcall);
+ break;
case SIMCALL_PROCESS_AUTO_RESTART_SET:
SIMIX_process_auto_restart_set(simcall->process_auto_restart.process,simcall->process_auto_restart.auto_restart);
SIMIX_simcall_answer(simcall);
SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_SLEEP),\
SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_ON_EXIT),\
SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_AUTO_RESTART_SET),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_RESTART),\
SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_CREATE),\
SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_DESTROY),\
SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GEY_BY_NAME),\
int auto_restart;
} process_auto_restart;
+ struct {
+ smx_process_t process;
+ } process_restart;
+
struct {
const char *name;
smx_rdv_t result;
* \brief Add an on_exit function
* Add an on_exit function which will be executed when the process exits/is killed.
*/
-XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data) {
+XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
+{
smx_simcall_t simcall = SIMIX_simcall_mine();
simcall->call = SIMCALL_PROCESS_ON_EXIT;
* Will restart the process when the host comes back up if auto_restart is set to 1.
*/
-XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart) {
+XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart)
+{
smx_simcall_t simcall = SIMIX_simcall_mine();
simcall->call = SIMCALL_PROCESS_AUTO_RESTART_SET;
SIMIX_simcall_push(simcall->issuer);
}
+/**
+ * \ingroup simix_process_management
+ * \brief Restarts the process, killing it and starting it again from scratch.
+ */
+XBT_PUBLIC(void) simcall_process_restart(smx_process_t process)
+{
+ smx_simcall_t simcall = SIMIX_simcall_mine();
+
+ simcall->call = SIMCALL_PROCESS_RESTART;
+ simcall->process_restart.process = process;
+
+ SIMIX_simcall_push(simcall->issuer);
+}
/**
* \ingroup simix_process_management
* \brief Creates a new sleep SIMIX action.