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 {
simdata_host_t simdata; /**< @brief simulator data */
void *data; /**< @brief user data */
} s_m_host_t;
+
/** @brief Host datatype
@ingroup m_datatypes_management
@{ */
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 {
char *category; /* task category for instrumentation */
#endif
} s_m_task_t;
+
/** @brief Task datatype
@ingroup m_datatypes_management
/** @} */
-
-
/* ****************************** 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 <em>code</em>, with some <em>private
+ A process may be defined as a <em>code</em>, with some <em>private
data</em>, executing in a <em>location</em>.
\see m_process_management
@{ */
-typedef struct m_process *m_process_t;
+typedef struct s_smx_process *m_process_t;
/** @} */
/* ********************************* Channel ******************************** */
/** @} */
-/* 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);
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);
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);
#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,
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;
/* 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();
*/
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;
{
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;
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();
"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
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;
{
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),
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;
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);
*/
/******************************** 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);
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;
}
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;
}
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;
}
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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);
}
*/
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
*/
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
*/
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);
}
*/
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);
}
*/
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);
}
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;
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 {
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();
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 */
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;
/************************** Global variables ********************************/
typedef struct MSG_Global {
xbt_fifo_t host;
- xbt_swag_t process_list;
int max_channel;
int PID;
int session;
/*************************************************************/
-#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.") */
"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);
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;
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);
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),\
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);
}
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,
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();
}
/**
- * \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)
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;
}
*
* \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);
}
}
- /* 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);
int SIMIX_process_get_maxpid(void) {
return simix_process_maxpid;
}
+
int SIMIX_process_count(void)
{
return xbt_swag_size(simix_global->process_list);
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;
}
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;
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;
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)
{
*/
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;
*/
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();
+ }
}
/**
*/
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;