From: Samuel Lepetit Date: Wed, 4 Jul 2012 13:25:59 +0000 (+0200) Subject: Fix SIMIX_process_kill(SIMIX_process_self()); issue: The killed processes mustn't... X-Git-Tag: v3_8~342 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/356d964ef596cb5f8905b6a6f54a1053d8ad86b6 Fix SIMIX_process_kill(SIMIX_process_self()); issue: The killed processes mustn't be added 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. --- diff --git a/include/msg/msg.h b/include/msg/msg.h index 1a9986c473..42a21e72ee 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -157,6 +157,8 @@ XBT_PUBLIC(int) MSG_process_is_suspended(msg_process_t 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, diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index f1c82114b2..e45226817f 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -120,8 +120,9 @@ typedef struct s_smx_context_factory *smx_context_factory_t; /* 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 @@ -219,7 +220,7 @@ XBT_PUBLIC(void) SIMIX_clean(void); 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); @@ -352,6 +353,7 @@ XBT_PUBLIC(xbt_dict_t) simcall_process_get_properties(smx_process_t host); 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); diff --git a/src/msg/msg_global.c b/src/msg/msg_global.c index eb807e6aee..5383a202e5 100644 --- a/src/msg/msg_global.c +++ b/src/msg/msg_global.c @@ -54,7 +54,6 @@ void MSG_init_nocheck(int *argc, char **argv) { 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(); diff --git a/src/msg/msg_process.c b/src/msg/msg_process.c index f511d47456..ba3943ddfa 100644 --- a/src/msg/msg_process.c +++ b/src/msg/msg_process.c @@ -45,7 +45,6 @@ void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc) #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); @@ -500,3 +499,10 @@ 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) { 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); +} diff --git a/src/simix/smx_context_base.c b/src/simix/smx_context_base.c index 56efcf1403..8fd10e4865 100644 --- a/src/simix/smx_context_base.c +++ b/src/simix/smx_context_base.c @@ -65,7 +65,6 @@ smx_ctx_base_factory_create_context_sized(size_t size, void smx_ctx_base_free(smx_context_t context) { int i; - if (context) { /* free argv */ diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index bc03b95d7d..52c0aca250 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -358,7 +358,7 @@ XBT_INLINE void SIMIX_function_register_process_create(smx_creation_func_t * * \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; diff --git a/src/simix/smx_private.h b/src/simix/smx_private.h index 5bd6499f18..472d5233ff 100644 --- a/src/simix/smx_private.h +++ b/src/simix/smx_private.h @@ -37,7 +37,7 @@ typedef struct s_smx_global { 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; diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index ecd9e5005d..d6aa7da289 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -224,7 +224,6 @@ void SIMIX_process_create(smx_process_t *process, *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); @@ -296,8 +295,9 @@ void SIMIX_process_runall(void) * 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); @@ -335,8 +335,10 @@ void SIMIX_process_kill(smx_process_t process) { 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); + } + } /** @@ -349,7 +351,7 @@ void SIMIX_process_killall(smx_process_t issuer) while ((p = xbt_swag_extract(simix_global->process_list))) { if (p != issuer) { - SIMIX_process_kill(p); + SIMIX_process_kill(p,issuer); } } @@ -780,3 +782,56 @@ void SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data) 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); + + } + +} diff --git a/src/simix/smx_process_private.h b/src/simix/smx_process_private.h index a87613c8e8..dbd1a6224b 100644 --- a/src/simix/smx_process_private.h +++ b/src/simix/smx_process_private.h @@ -71,7 +71,7 @@ void SIMIX_process_create(smx_process_t *process, 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); @@ -104,6 +104,6 @@ void SIMIX_process_sleep_suspend(smx_action_t action); 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 diff --git a/src/simix/smx_smurf.c b/src/simix/smx_smurf.c index 8ade58f3ef..214f0227c0 100644 --- a/src/simix/smx_smurf.c +++ b/src/simix/smx_smurf.c @@ -318,7 +318,7 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value) 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; @@ -334,8 +334,8 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value) 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; @@ -364,6 +364,10 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value) 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); diff --git a/src/simix/smx_smurf_private.h b/src/simix/smx_smurf_private.h index 3fe6281247..27f736e922 100644 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@ -47,6 +47,7 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_GET_PROPERTIES),\ 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),\ @@ -303,6 +304,10 @@ typedef struct s_smx_simcall { int auto_restart; } process_auto_restart; + struct { + smx_process_t process; + } process_restart; + struct { const char *name; smx_rdv_t result; diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 31b9c52cc8..004954ff25 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -653,7 +653,8 @@ xbt_dict_t simcall_process_get_properties(smx_process_t process) * \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; @@ -669,7 +670,8 @@ XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fu * 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; @@ -678,6 +680,19 @@ XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int aut 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.