From: thiery Date: Tue, 22 Feb 2011 16:03:39 +0000 (+0000) Subject: Simplify the management of processes in MSG. X-Git-Tag: v3.6_beta2~240 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/15142e98775405b23e3059da088d4aeecb906b78 Simplify the management of processes in MSG. - I removed the MSG global list of processes, which was useless and not thread-safe: this fixes parallel simulations that crashed at the end - The structure m_process_t is now an alias of smx_process_t - The name of each process was duplicated: one in MSG and one in SIMIX git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@9703 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/include/msg/datatypes.h b/include/msg/datatypes.h index d77e87634b..1954c7dc26 100644 --- a/include/msg/datatypes.h +++ b/include/msg/datatypes.h @@ -12,9 +12,11 @@ SG_BEGIN_DECL() /* ******************************** Host ************************************ */ + /** @defgroup m_datatypes_management_details Details on MSG datatypes @ingroup m_datatypes_management*/ typedef struct simdata_host *simdata_host_t; + /** @brief Host datatype @ingroup m_datatypes_management_details */ typedef struct m_host { @@ -22,6 +24,7 @@ typedef struct m_host { simdata_host_t simdata; /**< @brief simulator data */ void *data; /**< @brief user data */ } s_m_host_t; + /** @brief Host datatype @ingroup m_datatypes_management @@ -36,9 +39,11 @@ typedef struct m_host { @{ */ typedef struct m_host *m_host_t; /** @} */ + /* ******************************** Task ************************************ */ typedef struct simdata_task *simdata_task_t; + /** @brief Task datatype @ingroup m_datatypes_management_details */ typedef struct m_task { @@ -50,6 +55,7 @@ typedef struct m_task { char *category; /* task category for instrumentation */ #endif } s_m_task_t; + /** @brief Task datatype @ingroup m_datatypes_management @@ -76,28 +82,16 @@ typedef struct msg_comm *msg_comm_t; /** @} */ - - /* ****************************** Process *********************************** */ -typedef struct simdata_process *simdata_process_t; -/** @brief Process datatype - @ingroup m_datatypes_management_details @{ */ -typedef struct m_process { - s_xbt_swag_hookup_t process_list_hookup; - char *name; /**< @brief process name if any */ - simdata_process_t simdata; - /**< @brief simulator data */ - void *data; /**< @brief user data */ -} s_m_process_t; -/** @} */ -/** @brief Agent datatype + +/** @brief Process datatype @ingroup m_datatypes_management - An agent may be defined as a code, with some private + A process may be defined as a code, with some private data, executing in a location. \see m_process_management @{ */ -typedef struct m_process *m_process_t; +typedef struct s_smx_process *m_process_t; /** @} */ /* ********************************* Channel ******************************** */ diff --git a/include/simix/datatypes.h b/include/simix/datatypes.h index e69c1dfe3e..12fb1483dd 100644 --- a/include/simix/datatypes.h +++ b/include/simix/datatypes.h @@ -69,22 +69,24 @@ typedef struct s_smx_process *smx_process_t; /** @} */ -/* User create and kill process, the function must accept the folling parameters: +/* + * Type of function that creates a process. + * The function must accept the following parameters: * void* process: the process created will be stored there * const char *name: a name for the object. It is for user-level information and can be NULL * xbt_main_func_t code: is a function describing the behavior of the agent * void *data: data a pointer to any data one may want to attach to the new object. * smx_host_t host: the location where the new agent is executed * int argc, char **argv: parameters passed to code - * - * */ -typedef void (*smx_creation_func_t) ( /* process */ void *, - /*name */ const char *, - /*code */ xbt_main_func_t, - /*userdata */ void *, - /*hostname */ char *, + * xbt_dict_t pros: properties + */ +typedef void (*smx_creation_func_t) ( /* process */ smx_process_t*, + /* name */ const char*, + /* code */ xbt_main_func_t, + /* userdata */ void*, + /* hostname */ const char*, /* argc */ int, - /* argv */ char **, + /* argv */ char**, /* props */ xbt_dict_t); diff --git a/include/simix/simix.h b/include/simix/simix.h index b0911f6466..e748910d6a 100644 --- a/include/simix/simix.h +++ b/include/simix/simix.h @@ -24,7 +24,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_f_pvoid_t function); +XBT_PUBLIC(void) SIMIX_function_register_process_kill(void_pfn_smxprocess_t function); /* Simulation execution */ XBT_PUBLIC(void) SIMIX_run(void); @@ -125,6 +125,7 @@ XBT_PUBLIC(void) SIMIX_req_process_create(smx_process_t *process, xbt_dict_t properties); XBT_PUBLIC(void) SIMIX_req_process_kill(smx_process_t process); +XBT_PUBLIC(void) SIMIX_req_process_killall(void); /* Process handling */ XBT_PUBLIC(void) SIMIX_req_process_cleanup(smx_process_t process); diff --git a/src/include/simix/context.h b/src/include/simix/context.h index be146fe36a..072ab5dfc2 100644 --- a/src/include/simix/context.h +++ b/src/include/simix/context.h @@ -10,11 +10,11 @@ #include "xbt/misc.h" /* XBT_PUBLIC(), SG_BEGIN_DECL() and SG_END_DECL() definitions */ #include "xbt/function_types.h" /* function pointer types declarations */ #include "xbt_modinter.h" /* xbt_context_init() and xbt_context_exit() declarations */ +#include "simix/simix.h" SG_BEGIN_DECL() typedef struct s_xbt_context *xbt_context_t; -typedef void (*void_pfn_smxprocess_t) (smx_process_t); XBT_PUBLIC(xbt_context_t) xbt_context_new(const char *name, diff --git a/src/msg/global.c b/src/msg/global.c index 9ac1659c3c..02b300cb02 100644 --- a/src/msg/global.c +++ b/src/msg/global.c @@ -64,8 +64,6 @@ void MSG_global_init(int *argc, char **argv) msg_global = xbt_new0(s_MSG_Global_t, 1); - s_m_process_t p; - msg_global->process_list = xbt_swag_new(xbt_swag_offset(p, process_list_hookup)); msg_global->host = xbt_fifo_new(); msg_global->max_channel = 0; msg_global->PID = 1; @@ -74,9 +72,9 @@ void MSG_global_init(int *argc, char **argv) /* initialization of the action module */ _MSG_action_init(); - SIMIX_function_register_process_create(_MSG_process_create_from_SIMIX); - SIMIX_function_register_process_cleanup(__MSG_process_cleanup); - SIMIX_function_register_process_kill(_MSG_process_kill_from_SIMIX); + 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_from_SIMIX); } #ifdef HAVE_TRACING TRACE_start(); @@ -162,13 +160,7 @@ MSG_error_t MSG_main(void) */ int MSG_process_killall(int reset_PIDs) { - m_process_t p = NULL; - m_process_t self = MSG_process_self(); - - while ((p = xbt_swag_extract(msg_global->process_list))) { - if (p != self) - MSG_process_kill(p); - } + SIMIX_req_process_killall(); if (reset_PIDs > 0) { msg_global->PID = reset_PIDs; @@ -186,21 +178,17 @@ MSG_error_t MSG_clean(void) { xbt_fifo_item_t i = NULL; m_host_t h = NULL; - m_process_t p = NULL; #ifdef HAVE_TRACING TRACE_surf_release(); #endif - while ((p = xbt_swag_extract(msg_global->process_list))) { - MSG_process_kill(p); - } + MSG_process_killall(0); xbt_fifo_foreach(msg_global->host, i, h, m_host_t) { __MSG_host_destroy(h); } xbt_fifo_free(msg_global->host); - xbt_swag_free(msg_global->process_list); free(msg_global); msg_global = NULL; diff --git a/src/msg/gos.c b/src/msg/gos.c index 1de05761f6..db0ffdaa31 100644 --- a/src/msg/gos.c +++ b/src/msg/gos.c @@ -37,7 +37,7 @@ MSG_error_t MSG_get_errno(void) MSG_error_t MSG_task_execute(m_task_t task) { simdata_task_t simdata = NULL; - m_process_t self = MSG_process_self(); + simdata_process_t p_simdata; e_smx_state_t comp_state; CHECK_HOST(); @@ -54,7 +54,7 @@ MSG_error_t MSG_task_execute(m_task_t task) "This task is executed somewhere else. Go fix your code! %d", task->simdata->isused); - XBT_DEBUG("Computing on %s", MSG_process_self()->simdata->m_host->name); + XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->computation_amount == 0) { #ifdef HAVE_TRACING @@ -71,9 +71,10 @@ MSG_error_t MSG_task_execute(m_task_t task) SIMIX_req_set_category(simdata->compute, task->category); #endif - self->simdata->waiting_action = simdata->compute; + p_simdata = SIMIX_process_self_get_data(); + p_simdata->waiting_action = simdata->compute; comp_state = SIMIX_req_host_execution_wait(simdata->compute); - self->simdata->waiting_action = NULL; + p_simdata->waiting_action = NULL; simdata->isused=0; @@ -166,10 +167,11 @@ MSG_error_t MSG_parallel_task_execute(m_task_t task) { simdata_task_t simdata = NULL; e_smx_state_t comp_state; - m_process_t self = MSG_process_self(); + simdata_process_t p_simdata; CHECK_HOST(); simdata = task->simdata; + p_simdata = SIMIX_process_self_get_data(); xbt_assert0((!simdata->compute) && (task->simdata->isused == 0), @@ -178,7 +180,7 @@ MSG_error_t MSG_parallel_task_execute(m_task_t task) xbt_assert0(simdata->host_nb, "This is not a parallel task. Go to hell."); - XBT_DEBUG("Parallel computing on %s", MSG_process_self()->simdata->m_host->name); + XBT_DEBUG("Parallel computing on %s", p_simdata->m_host->name); simdata->isused=1; @@ -189,9 +191,9 @@ MSG_error_t MSG_parallel_task_execute(m_task_t task) simdata->comm_amount, 1.0, -1.0); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); - self->simdata->waiting_action = simdata->compute; + p_simdata->waiting_action = simdata->compute; comp_state = SIMIX_req_host_execution_wait(simdata->compute); - self->simdata->waiting_action = NULL; + p_simdata->waiting_action = NULL; XBT_DEBUG("Finished waiting for execution of action %p, state = %d", simdata->compute, comp_state); diff --git a/src/msg/m_process.c b/src/msg/m_process.c index ba8115e874..b54f233e44 100644 --- a/src/msg/m_process.c +++ b/src/msg/m_process.c @@ -26,45 +26,30 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg, */ /******************************** Process ************************************/ -void __MSG_process_cleanup(smx_process_t smx_proc) +void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc) { - - m_process_t proc; + simdata_process_t msg_proc; if (smx_proc == SIMIX_process_self()) { /* avoid a SIMIX request if this function is called by the process itself */ - proc = SIMIX_process_self_get_data(); + msg_proc = SIMIX_process_self_get_data(); } else { - proc = SIMIX_req_process_get_data(smx_proc); + msg_proc = SIMIX_req_process_get_data(smx_proc); } #ifdef HAVE_TRACING - TRACE_msg_process_end(proc); + TRACE_msg_process_end(smx_proc); #endif - if (msg_global) - xbt_swag_remove(proc, msg_global->process_list); - + xbt_free(msg_proc); SIMIX_req_process_cleanup(smx_proc); - - if (proc->name) { - free(proc->name); - proc->name = NULL; - } - if (proc->simdata) { - free(proc->simdata); - proc->simdata = NULL; - } - free(proc); - - return; } /* This function creates a MSG process. It has the prototype enforced by SIMIX_function_register_process_create */ -void _MSG_process_create_from_SIMIX(void* process, const char *name, +void MSG_process_create_from_SIMIX(smx_process_t* process, const char *name, xbt_main_func_t code, void *data, - char *hostname, int argc, char **argv, + const char *hostname, int argc, char **argv, xbt_dict_t properties) { m_host_t host = MSG_get_host_by_name(hostname); @@ -154,48 +139,38 @@ m_process_t MSG_process_create_with_environment(const char *name, int argc, char **argv, xbt_dict_t properties) { - simdata_process_t simdata = NULL; - m_process_t process = xbt_new0(s_m_process_t, 1); - xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters"); + xbt_assert0(code != NULL && host != NULL, "Invalid parameters"); + simdata_process_t simdata = xbt_new0(s_simdata_process_t, 1); + m_process_t process; - simdata = xbt_new0(s_simdata_process_t, 1); - - /* Simulator Data */ + /* Simulator data for MSG */ simdata->PID = msg_global->PID++; simdata->waiting_action = NULL; simdata->waiting_task = NULL; simdata->m_host = host; simdata->argc = argc; simdata->argv = argv; + simdata->data = data; + simdata->last_errno = MSG_OK; if (SIMIX_process_self()) { - simdata->PPID = MSG_process_get_PID(SIMIX_process_self_get_data()); + simdata->PPID = MSG_process_get_PID(MSG_process_self()); } else { simdata->PPID = -1; } - simdata->last_errno = MSG_OK; - - /* Process structure */ - process->name = xbt_strdup(name); - process->simdata = simdata; - process->data = data; - xbt_swag_insert(process, msg_global->process_list); - -#ifdef HAVE_TRACING - TRACE_msg_process_create (process); -#endif /* Let's create the process: SIMIX may decide to start it right now, * even before returning the flow control to us */ - SIMIX_req_process_create(&simdata->s_process, name, code, (void *) process, host->name, + SIMIX_req_process_create(&process, name, code, simdata, host->name, argc, argv, properties); - if (!simdata->s_process) { +#ifdef HAVE_TRACING + TRACE_msg_process_create(process); +#endif + + if (!process) { /* Undo everything we have just changed */ msg_global->PID--; - xbt_swag_remove(process, msg_global->process_list); - xbt_free(process->name); - xbt_free(process); xbt_free(simdata); return NULL; } @@ -203,36 +178,32 @@ m_process_t MSG_process_create_with_environment(const char *name, return process; } -void _MSG_process_kill_from_SIMIX(void *p) +void MSG_process_kill_from_SIMIX(smx_process_t p) { #ifdef HAVE_TRACING - TRACE_msg_process_kill((m_process_t) p); + TRACE_msg_process_kill(p); #endif - MSG_process_kill((m_process_t) p); + MSG_process_kill(p); } /** \ingroup m_process_management * \param process poor victim * - * This function simply kills a \a process... scarry isn't it ? :) + * This function simply kills a \a process... scary isn't it ? :) */ void MSG_process_kill(m_process_t process) { - simdata_process_t p_simdata = process->simdata; - #ifdef HAVE_TRACING TRACE_msg_process_kill(process); #endif - XBT_DEBUG("Killing %s(%d) on %s", - process->name, p_simdata->PID, p_simdata->m_host->name); - + /* FIXME: why do we only cancel communication actions? is this useful? */ + simdata_process_t p_simdata = SIMIX_req_process_get_data(process); if (p_simdata->waiting_task && p_simdata->waiting_task->simdata->comm) { SIMIX_req_comm_cancel(p_simdata->waiting_task->simdata->comm); } - xbt_swag_remove(process, msg_global->process_list); - SIMIX_req_process_kill(process->simdata->s_process); + SIMIX_req_process_kill(process); return; } @@ -246,40 +217,43 @@ void MSG_process_kill(m_process_t process) MSG_error_t MSG_process_change_host(m_host_t host) { m_process_t process = MSG_process_self(); - m_host_t now = process->simdata->m_host; - process->simdata->m_host = host; + simdata_process_t simdata = SIMIX_process_self_get_data(); + m_host_t now = simdata->m_host; + simdata->m_host = host; #ifdef HAVE_TRACING TRACE_msg_process_change_host(process, now, host); #endif - SIMIX_req_process_change_host(process->simdata->s_process, now->name, - host->name); + SIMIX_req_process_change_host(process, now->name, host->name); return MSG_OK; } /** \ingroup m_process_management - * \brief Return the user data of a #m_process_t. + * \brief Returns the user data of a process. * * This function checks whether \a process is a valid pointer or not - and return the user data associated to \a process if it is possible. + and returns the user data associated to this process. */ -void *MSG_process_get_data(m_process_t process) +void* MSG_process_get_data(m_process_t process) { - xbt_assert0((process != NULL), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); - return (process->data); + /* get from SIMIX the MSG process data, and then the user data */ + simdata_process_t simdata = SIMIX_req_process_get_data(process); + return simdata->data; } /** \ingroup m_process_management - * \brief Set the user data of a #m_process_t. + * \brief Sets the user data of a process. * * This function checks whether \a process is a valid pointer or not - and set the user data associated to \a process if it is possible. + and sets the user data associated to this process. */ MSG_error_t MSG_process_set_data(m_process_t process, void *data) { - xbt_assert0((process != NULL), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); - process->data = data; + simdata_process_t simdata = SIMIX_req_process_get_data(process); + simdata->data = data; return MSG_OK; } @@ -293,10 +267,10 @@ MSG_error_t MSG_process_set_data(m_process_t process, void *data) */ m_host_t MSG_process_get_host(m_process_t process) { - xbt_assert0(((process != NULL) - && (process->simdata)), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); - return (((simdata_process_t) process->simdata)->m_host); + simdata_process_t simdata = SIMIX_req_process_get_data(process); + return simdata->m_host; } /** \ingroup m_process_management @@ -309,13 +283,9 @@ m_host_t MSG_process_get_host(m_process_t process) */ m_process_t MSG_process_from_PID(int PID) { - m_process_t process = NULL; - - xbt_swag_foreach(process, msg_global->process_list) { - if (MSG_process_get_PID(process) == PID) - return process; - } - return NULL; + /* FIXME: reimplement this function using SIMIX when we have a good PID. + * In the meantime, I guess nobody uses it so it should not break anything. */ + THROW_UNIMPLEMENTED; } /** \ingroup m_process_management @@ -326,12 +296,15 @@ m_process_t MSG_process_from_PID(int PID) */ int MSG_process_get_PID(m_process_t process) { - /* Do not raise an exception here: this function is used in the logs, - and it will be called back by the exception handling stuff */ - if (process == NULL || process->simdata == NULL) + /* Do not raise an exception here: this function is called by the logs + * and the exceptions, so it would be called back again and again */ + if (process == NULL) { return 0; + } + + simdata_process_t simdata = SIMIX_req_process_get_data(process); - return (((simdata_process_t) process->simdata)->PID); + return simdata != NULL ? simdata->PID : 0; } /** \ingroup m_process_management @@ -343,10 +316,11 @@ int MSG_process_get_PID(m_process_t process) */ int MSG_process_get_PPID(m_process_t process) { - xbt_assert0(((process != NULL) - && (process->simdata)), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); - return (((simdata_process_t) process->simdata)->PPID); + simdata_process_t simdata = SIMIX_req_process_get_data(process); + + return simdata->PPID; } /** \ingroup m_process_management @@ -357,11 +331,9 @@ int MSG_process_get_PPID(m_process_t process) */ const char *MSG_process_get_name(m_process_t process) { - xbt_assert0(process, "Invalid parameter: process is NULL"); - xbt_assert0(process->simdata, - "Invalid parameter: process->simdata is NULL"); + xbt_assert0(process, "Invalid parameter"); - return (process->name); + return SIMIX_req_process_get_name(process); } /** \ingroup m_process_management @@ -384,10 +356,9 @@ const char *MSG_process_get_property_value(m_process_t process, */ xbt_dict_t MSG_process_get_properties(m_process_t process) { - xbt_assert0((process != NULL), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); - return (SIMIX_req_process_get_properties - (((simdata_process_t) process->simdata)->s_process)); + return SIMIX_req_process_get_properties(process); } @@ -398,7 +369,7 @@ xbt_dict_t MSG_process_get_properties(m_process_t process) */ int MSG_process_self_PID(void) { - return (MSG_process_get_PID(MSG_process_self())); + return MSG_process_get_PID(MSG_process_self()); } /** \ingroup m_process_management @@ -409,19 +380,17 @@ int MSG_process_self_PID(void) */ int MSG_process_self_PPID(void) { - return (MSG_process_get_PPID(MSG_process_self())); + return MSG_process_get_PPID(MSG_process_self()); } /** \ingroup m_process_management - * \brief Return the current agent. + * \brief Return the current process. * * This function returns the currently running #m_process_t. */ m_process_t MSG_process_self(void) { - /* we cannot make a SIMIX request here because this may create an exception or a logging - event, and both mechanisms call MSG_process_self() again (via xbt_getpid()) */ - return (m_process_t) SIMIX_process_self_get_data(); + return SIMIX_process_self(); } /** \ingroup m_process_management @@ -432,15 +401,14 @@ m_process_t MSG_process_self(void) */ MSG_error_t MSG_process_suspend(m_process_t process) { - xbt_assert0(((process != NULL) - && (process->simdata)), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); CHECK_HOST(); #ifdef HAVE_TRACING TRACE_msg_process_suspend(process); #endif - SIMIX_req_process_suspend(process->simdata->s_process); + SIMIX_req_process_suspend(process); MSG_RETURN(MSG_OK); } @@ -452,16 +420,14 @@ MSG_error_t MSG_process_suspend(m_process_t process) */ MSG_error_t MSG_process_resume(m_process_t process) { - - xbt_assert0(((process != NULL) - && (process->simdata)), "Invalid parameters"); + xbt_assert0(process != NULL, "Invalid parameter"); CHECK_HOST(); #ifdef HAVE_TRACING TRACE_msg_process_resume(process); #endif - SIMIX_req_process_resume(process->simdata->s_process); + SIMIX_req_process_resume(process); MSG_RETURN(MSG_OK); } @@ -473,12 +439,10 @@ MSG_error_t MSG_process_resume(m_process_t process) */ int MSG_process_is_suspended(m_process_t process) { - xbt_assert0(((process != NULL) - && (process->simdata)), "Invalid parameters"); - return SIMIX_req_process_is_suspended(process->simdata->s_process); + xbt_assert0(process != NULL, "Invalid parameter"); + return SIMIX_req_process_is_suspended(process); } - smx_context_t MSG_process_get_smx_ctx(m_process_t process) { - return SIMIX_process_get_context(process->simdata->s_process); + return SIMIX_process_get_context(process); } diff --git a/src/msg/msg_mailbox.c b/src/msg/msg_mailbox.c index 62b007b0d7..6700ed73b8 100644 --- a/src/msg/msg_mailbox.c +++ b/src/msg/msg_mailbox.c @@ -130,6 +130,7 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task, MSG_error_t ret = MSG_OK; simdata_task_t t_simdata = NULL; m_process_t process = MSG_process_self(); + simdata_process_t p_simdata = SIMIX_process_self_get_data(); #ifdef HAVE_TRACING volatile smx_action_t comm = NULL; int call_end = 0; @@ -151,7 +152,8 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task, t_simdata->isused=1; msg_global->sent_msg++; - process->simdata->waiting_task = task; + + p_simdata->waiting_task = task; /* Try to send it by calling SIMIX network layer */ TRY { @@ -187,7 +189,7 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task, t_simdata->isused = 0; } - process->simdata->waiting_task = NULL; + p_simdata->waiting_task = NULL; #ifdef HAVE_TRACING if (call_end) TRACE_msg_task_put_end(); diff --git a/src/msg/private.h b/src/msg/private.h index aec09a2763..f4f74b88bc 100644 --- a/src/msg/private.h +++ b/src/msg/private.h @@ -49,7 +49,6 @@ typedef struct simdata_task { typedef struct simdata_process { m_host_t m_host; /* the host on which the process is running */ - smx_process_t s_process; int PID; /* used for debugging purposes */ int PPID; /* The parent PID */ m_host_t put_host; /* used for debugging purposes */ @@ -59,7 +58,8 @@ typedef struct simdata_process { int argc; /* arguments number if any */ char **argv; /* arguments table if any */ MSG_error_t last_errno; /* the last value returned by a MSG_function */ -} s_simdata_process_t; + void* data; /* user data */ +} s_simdata_process_t, *simdata_process_t; typedef struct process_arg { const char *name; @@ -81,7 +81,6 @@ typedef struct msg_comm { /************************** Global variables ********************************/ typedef struct MSG_Global { xbt_fifo_t host; - xbt_swag_t process_list; int max_channel; int PID; int session; @@ -94,8 +93,10 @@ XBT_PUBLIC_DATA(MSG_Global_t) msg_global; /*************************************************************/ -#define PROCESS_SET_ERRNO(val) (MSG_process_self()->simdata->last_errno=val) -#define PROCESS_GET_ERRNO() (MSG_process_self()->simdata->last_errno) +#define PROCESS_SET_ERRNO(val) \ + (((simdata_process_t) SIMIX_process_self_get_data())->last_errno=val) +#define PROCESS_GET_ERRNO() \ + (((simdata_process_t) SIMIX_process_self_get_data())->last_errno) #define MSG_RETURN(val) do {PROCESS_SET_ERRNO(val);return(val);} while(0) /* #define CHECK_ERRNO() ASSERT((PROCESS_GET_ERRNO()!=MSG_HOST_FAILURE),"Host failed, you cannot call this function.") */ @@ -103,19 +104,17 @@ XBT_PUBLIC_DATA(MSG_Global_t) msg_global; "Host failed, you cannot call this function. (state=%d)",SIMIX_req_host_get_state(SIMIX_host_self()))*/ #define CHECK_HOST() - m_host_t __MSG_host_create(smx_host_t workstation, void *data); - void __MSG_host_destroy(m_host_t host); void __MSG_display_process_status(void); -void __MSG_process_cleanup(smx_process_t smx_proc); -void _MSG_process_create_from_SIMIX(void *process, const char *name, - xbt_main_func_t code, void *data, - char *hostname, int argc, - char **argv, xbt_dict_t properties); -void _MSG_process_kill_from_SIMIX(void *p); +void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc); +void MSG_process_create_from_SIMIX(smx_process_t *process, const char *name, + xbt_main_func_t code, void *data, + const char *hostname, int argc, + char **argv, xbt_dict_t properties); +void MSG_process_kill_from_SIMIX(smx_process_t p); void _MSG_action_init(void); void _MSG_action_exit(void); diff --git a/src/simix/private.h b/src/simix/private.h index d63145dbf6..09c76f4fb0 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -36,7 +36,7 @@ typedef struct s_smx_global { smx_process_t maestro_process; xbt_dict_t registered_functions; smx_creation_func_t create_process_function; - void_f_pvoid_t kill_process_function; + void_pfn_smxprocess_t kill_process_function; void_pfn_smxprocess_t cleanup_process_function; xbt_mallocator_t action_mallocator; } s_smx_global_t, *smx_global_t; diff --git a/src/simix/process_private.h b/src/simix/process_private.h index 7a265549e2..5d06f2c95b 100644 --- a/src/simix/process_private.h +++ b/src/simix/process_private.h @@ -52,8 +52,8 @@ void SIMIX_process_create(smx_process_t *process, const char *hostname, int argc, char **argv, xbt_dict_t properties); -void SIMIX_process_kill(smx_process_t process, smx_process_t killer); -void SIMIX_process_killall(void); +void SIMIX_process_kill(smx_process_t process); +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_cleanup(smx_process_t arg); diff --git a/src/simix/smurf_private.h b/src/simix/smurf_private.h index 97cbbd83e6..7c2dd90ce2 100644 --- a/src/simix/smurf_private.h +++ b/src/simix/smurf_private.h @@ -32,6 +32,7 @@ SIMIX_REQ_ENUM_ELEMENT(REQ_HOST_EXECUTION_SET_PRIORITY),\ SIMIX_REQ_ENUM_ELEMENT(REQ_HOST_EXECUTION_WAIT),\ SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_CREATE),\ SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_KILL),\ +SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_KILLALL),\ SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_CLEANUP),\ SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_CHANGE_HOST),\ SIMIX_REQ_ENUM_ELEMENT(REQ_PROCESS_SUSPEND),\ diff --git a/src/simix/smx_deployment.c b/src/simix/smx_deployment.c index 62815cf9fe..87d3f6151a 100644 --- a/src/simix/smx_deployment.c +++ b/src/simix/smx_deployment.c @@ -82,10 +82,9 @@ static void parse_process_finalize(void) return; } if (kill_time > SIMIX_get_clock()) { - if (simix_global->kill_process_function) + if (simix_global->kill_process_function) { SIMIX_timer_set(start_time, simix_global->kill_process_function, process); - else - SIMIX_timer_set(start_time, &SIMIX_process_kill, process); + } } xbt_free(parse_host); } diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index 9be8bd2b51..3681493839 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -80,8 +80,8 @@ void SIMIX_global_init(int *argc, char **argv) simix_global->maestro_process = NULL; simix_global->registered_functions = xbt_dict_new(); - simix_global->create_process_function = NULL; - simix_global->kill_process_function = NULL; + simix_global->create_process_function = SIMIX_process_create; + simix_global->kill_process_function = SIMIX_process_kill; simix_global->cleanup_process_function = SIMIX_process_cleanup; simix_global->action_mallocator = xbt_mallocator_new(65536, SIMIX_action_mallocator_new_f, SIMIX_action_mallocator_free_f, @@ -117,7 +117,7 @@ void SIMIX_global_init(int *argc, char **argv) void SIMIX_clean(void) { /* Kill everyone (except maestro) */ - SIMIX_process_killall(); + SIMIX_process_killall(simix_global->maestro_process); /* Exit the SIMIX network module */ SIMIX_network_exit(); @@ -250,43 +250,40 @@ XBT_INLINE void SIMIX_timer_set(double date, void *function, void *arg) } /** - * \brief Registers a function to create a process. - * - * This function registers an user function to be called when a new process is created. The user function have to call the SIMIX_create_process function. - * \param function Create process function + * \brief Registers a function to create a process. * + * This function registers a function to be called + * when a new process is created. The function has + * to call SIMIX_process_create(). + * \param function create process function */ XBT_INLINE void SIMIX_function_register_process_create(smx_creation_func_t function) { - xbt_assert0((simix_global->create_process_function == NULL), - "Data already set"); - simix_global->create_process_function = function; } /** - * \brief Registers a function to kill a process. + * \brief Registers a function to kill a process. * - * This function registers an user function to be called when a new process is killed. The user function have to call the SIMIX_kill_process function. - * \param function Kill process function + * This function registers a function to be called when a + * process is killed. The function has to call the SIMIX_process_kill(). * + * \param function Kill process function */ -XBT_INLINE void SIMIX_function_register_process_kill(void_f_pvoid_t +XBT_INLINE void SIMIX_function_register_process_kill(void_pfn_smxprocess_t function) { - xbt_assert0((simix_global->kill_process_function == NULL), - "Data already set"); - simix_global->kill_process_function = function; } /** - * \brief Registers a function to cleanup a process. + * \brief Registers a function to cleanup a process. * - * This function registers an user function to be called when a new process ends properly. - * \param function cleanup process function + * This function registers a user function to be called when + * a process ends properly. * + * \param function cleanup process function */ XBT_INLINE void SIMIX_function_register_process_cleanup(void_pfn_smxprocess_t function) diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index 2a251ddef7..da17c3a7f6 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -94,31 +94,15 @@ void SIMIX_create_maestro_process() smx_process_t SIMIX_process_create_from_wrapper(smx_process_arg_t args) { smx_process_t process; - - if (simix_global->create_process_function) { - simix_global->create_process_function( - &process, - args->name, - args->code, - args->data, - args->hostname, - args->argc, - args->argv, - args->properties); - } - else { - SIMIX_process_create( - &process, - args->name, - args->code, - args->data, - args->hostname, - args->argc, - args->argv, - args->properties); - } - // FIXME: to simplify this, simix_global->create_process_function could just - // be SIMIX_process_create() by default (and the same thing in smx_deployment.c) + simix_global->create_process_function( + &process, + args->name, + args->code, + args->data, + args->hostname, + args->argc, + args->argv, + args->properties); return process; } @@ -190,7 +174,7 @@ void SIMIX_process_create(smx_process_t *process, * * \param process poor victim */ -void SIMIX_process_kill(smx_process_t process, smx_process_t killer) { +void SIMIX_process_kill(smx_process_t process) { XBT_DEBUG("Killing process %s on %s", process->name, process->smx_host->name); @@ -227,26 +211,22 @@ void SIMIX_process_kill(smx_process_t process, smx_process_t killer) { } } - /* If I'm killing myself then stop, otherwise schedule the process to kill. */ - if (process == killer) { - SIMIX_context_stop(process->context); - } - else { - xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process); - } + xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process); } /** * \brief Kills all running processes. - * - * Only maestro can kill everyone. + * \param issuer this one will not be killed */ -void SIMIX_process_killall(void) +void SIMIX_process_killall(smx_process_t issuer) { smx_process_t p = NULL; - while ((p = xbt_swag_extract(simix_global->process_list))) - SIMIX_process_kill(p, SIMIX_process_self()); + while ((p = xbt_swag_extract(simix_global->process_list))) { + if (p != issuer) { + SIMIX_process_kill(p); + } + } SIMIX_context_runall(simix_global->process_to_run); @@ -349,6 +329,7 @@ void SIMIX_process_resume(smx_process_t process, smx_process_t issuer) int SIMIX_process_get_maxpid(void) { return simix_process_maxpid; } + int SIMIX_process_count(void) { return xbt_swag_size(simix_global->process_list); @@ -543,6 +524,7 @@ void SIMIX_process_exception_terminate(xbt_ex_t * e) smx_context_t SIMIX_process_get_context(smx_process_t p) { return p->context; } + void SIMIX_process_set_context(smx_process_t p,smx_context_t c) { p->context = c; } diff --git a/src/simix/smx_smurf.c b/src/simix/smx_smurf.c index fb7d994f21..8ac0b0c4db 100644 --- a/src/simix/smx_smurf.c +++ b/src/simix/smx_smurf.c @@ -94,8 +94,8 @@ void SIMIX_request_answer(smx_req_t req) void SIMIX_request_pre(smx_req_t req, int value) { - switch (req->call) { + switch (req->call) { case REQ_COMM_TEST: SIMIX_pre_comm_test(req); break; @@ -362,7 +362,12 @@ void SIMIX_request_pre(smx_req_t req, int value) break; case REQ_PROCESS_KILL: - SIMIX_process_kill(req->process_kill.process, req->issuer); + SIMIX_process_kill(req->process_kill.process); + SIMIX_request_answer(req); + break; + + case REQ_PROCESS_KILLALL: + SIMIX_process_killall(req->issuer); SIMIX_request_answer(req); break; diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 78460582f9..f8bac30bb8 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -345,8 +345,18 @@ void SIMIX_req_process_kill(smx_process_t process) SIMIX_request_push(); } +/** \brief Kills all SIMIX processes. + */ +void SIMIX_req_process_killall(void) +{ + smx_req_t req = SIMIX_req_mine(); + + req->call = REQ_PROCESS_KILLALL; + SIMIX_request_push(); +} + /** \brief Cleans up a SIMIX process. - * \param process poor victim + * \param process poor victim (must have already been killed) */ void SIMIX_req_process_cleanup(smx_process_t process) { @@ -436,6 +446,11 @@ int SIMIX_req_process_count(void) */ void* SIMIX_req_process_get_data(smx_process_t process) { + if (process == SIMIX_process_self()) { + /* avoid a request if this function is called by the process itself */ + return SIMIX_process_self_get_data(); + } + smx_req_t req = SIMIX_req_mine(); req->call = REQ_PROCESS_GET_DATA; @@ -453,12 +468,19 @@ void* SIMIX_req_process_get_data(smx_process_t process) */ void SIMIX_req_process_set_data(smx_process_t process, void *data) { - smx_req_t req = SIMIX_req_mine(); + if (process == SIMIX_process_self()) { + /* avoid a request if this function is called by the process itself */ + SIMIX_process_self_set_data(data); + } + else { - req->call = REQ_PROCESS_SET_DATA; - req->process_set_data.process = process; - req->process_set_data.data = data; - SIMIX_request_push(); + smx_req_t req = SIMIX_req_mine(); + + req->call = REQ_PROCESS_SET_DATA; + req->process_set_data.process = process; + req->process_set_data.data = data; + SIMIX_request_push(); + } } /** @@ -487,6 +509,11 @@ smx_host_t SIMIX_req_process_get_host(smx_process_t process) */ const char* SIMIX_req_process_get_name(smx_process_t process) { + if (process == SIMIX_process_self()) { + /* avoid a request if this function is called by the process itself */ + return process->name; + } + smx_req_t req = SIMIX_req_mine(); req->call = REQ_PROCESS_GET_NAME;