-/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+/* Copyright (c) 2007-2012. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
simix_global->maestro_process = maestro;
return;
}
+/**
+ * \brief Stops a process.
+ *
+ * Stops the process, execute all the registered on_exit functions,
+ * register it to the list of the process to restart if needed
+ * and stops its context.
+ */
+void SIMIX_process_stop(smx_process_t arg) {
+ /* execute the on_exit functions */
+ SIMIX_process_on_exit_runall(arg);
+ /* Add the process to the list of process to restart, only if
+ * the host is down
+ */
+ if (arg->auto_restart && !SIMIX_host_get_state(arg->smx_host)) {
+ SIMIX_host_add_auto_restart_process(arg->smx_host,arg->name,arg->code, arg->data,
+ arg->smx_host->name,
+ arg->kill_time,
+ arg->argc,arg->argv,arg->properties,
+ arg->auto_restart);
+ }
+ XBT_DEBUG("Process %s (%s) is dead",arg->name,arg->smx_host->name);
+ /* stop the context */
+ SIMIX_context_stop(arg->context);
+}
/**
* \brief Same as SIMIX_process_create() but with only one argument (used by timers).
+ * This function frees the argument.
* \return the process created
*/
smx_process_t SIMIX_process_create_from_wrapper(smx_process_arg_t args) {
args->kill_time,
args->argc,
args->argv,
- args->properties);
-
+ args->properties,
+ args->auto_restart);
+ xbt_free(args);
return process;
}
const char *hostname,
double kill_time,
int argc, char **argv,
- xbt_dict_t properties) {
+ xbt_dict_t properties,
+ int auto_restart) {
*process = NULL;
smx_host_t host = SIMIX_host_get_by_name(hostname);
*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);
(*process)->data = data;
(*process)->comms = xbt_fifo_new();
(*process)->simcall.issuer = *process;
+ /* Process data for auto-restart */
+ (*process)->auto_restart = auto_restart;
+ (*process)->code = code;
+ (*process)->argc = argc;
+ (*process)->argv = argv;
+ (*process)->kill_time = kill_time;
+
XBT_VERB("Create context %s", (*process)->name);
(*process)->context = SIMIX_context_new(code, argc, argv,
* 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);
SIMIX_comm_destroy(process->waiting_action);
break;
- case SIMIX_ACTION_SLEEP:
- SIMIX_process_sleep_destroy(process->waiting_action);
- break;
+ case SIMIX_ACTION_SLEEP:
+ SIMIX_process_sleep_destroy(process->waiting_action);
+ break;
- case SIMIX_ACTION_SYNCHRO:
- SIMIX_synchro_stop_waiting(process, &process->simcall);
- SIMIX_synchro_destroy(process->waiting_action);
- break;
+ case SIMIX_ACTION_SYNCHRO:
+ SIMIX_synchro_stop_waiting(process, &process->simcall);
+ SIMIX_synchro_destroy(process->waiting_action);
+ break;
- case SIMIX_ACTION_IO:
- SIMIX_io_destroy(process->waiting_action);
- break;
+ case SIMIX_ACTION_IO:
+ SIMIX_io_destroy(process->waiting_action);
+ 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);
}
}
if (self->context->iwannadie){
XBT_DEBUG("I wanna die!");
- SIMIX_context_stop(self->context);
+ SIMIX_process_stop(self);
}
if(self->suspended) {
void SIMIX_process_exception_terminate(xbt_ex_t * e)
{
xbt_ex_display(e);
- abort();
+ xbt_abort();
}
smx_context_t SIMIX_process_get_context(smx_process_t p) {
xbt_assert(process, "current process not found: are you in maestro context ?");
if (!process->on_exit) {
- XBT_INFO("NEW : %p",process);
process->on_exit = xbt_dynar_new(sizeof(s_smx_process_exit_fun_t), NULL);
}
xbt_dynar_push_as(process->on_exit,s_smx_process_exit_fun_t,exit_fun);
}
+/**
+ * \brief Sets the auto-restart status of the process.
+ * If set to 1, the process will be automatically restarted when its host
+ * comes back.
+ */
+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.
+ */
+smx_process_t 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);
+
+ }
+ return new_process;
+}