#include "simgrid/datatypes.h"
#include "simgrid/host.h"
+
+#ifdef __cplusplus
+
+namespace simgrid {
+namespace simix {
+ class Context;
+ class ContextFactory;
+}
+}
+
+typedef simgrid::simix::Context *smx_context_t;
+
+#else
+
+typedef struct s_smx_context *smx_context_t;
+
+#endif
+
+
+
SG_BEGIN_DECL()
/**************************** Scalar Values **********************************/
XBT_PUBLIC(void*) SIMIX_comm_get_src_data(smx_synchro_t synchro);
XBT_PUBLIC(void*) SIMIX_comm_get_dst_data(smx_synchro_t synchro);
-/******************************** Context *************************************/
-typedef struct s_smx_context *smx_context_t;
-typedef struct s_smx_context_factory *smx_context_factory_t;
-
/* Process creation/destruction callbacks */
typedef void (*void_pfn_smxprocess_t) (smx_process_t);
-/* Process kill */
-typedef void (*void_pfn_smxprocess_t_smxprocess_t) (smx_process_t, smx_process_t);
/* for auto-restart function */
typedef void (*void_pfn_sghost_t) (sg_host_t);
-/* The following function pointer types describe the interface that any context
- factory should implement */
-
-
-typedef smx_context_t (*smx_pfn_context_factory_create_context_t)(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t, smx_process_t process);
-typedef int (*smx_pfn_context_factory_finalize_t) (smx_context_factory_t*);
-typedef void (*smx_pfn_context_free_t) (smx_context_t);
-typedef void (*smx_pfn_context_start_t) (smx_context_t);
-typedef void (*smx_pfn_context_stop_t) (smx_context_t);
-typedef void (*smx_pfn_context_suspend_t) (smx_context_t context);
-typedef void (*smx_pfn_context_runall_t) (void);
-typedef smx_context_t (*smx_pfn_context_self_t) (void);
-typedef smx_process_t (*smx_pfn_context_get_process_t) (smx_context_t context);
-
-/* interface of the context factories */
-typedef struct s_smx_context_factory {
- const char *name;
- smx_pfn_context_factory_create_context_t create_context;
- smx_pfn_context_factory_finalize_t finalize;
- smx_pfn_context_free_t free;
- smx_pfn_context_stop_t stop;
- smx_pfn_context_suspend_t suspend;
- smx_pfn_context_runall_t runall;
- smx_pfn_context_self_t self;
- smx_pfn_context_get_process_t get_process;
-} s_smx_context_factory_t;
-
-/* Hack: let msg load directly the right factory */
-typedef void (*smx_ctx_factory_initializer_t)(smx_context_factory_t*);
-XBT_PUBLIC_DATA(smx_ctx_factory_initializer_t) smx_factory_initializer_to_use;
extern char* smx_context_factory_name;
extern int smx_context_stack_size;
extern int smx_context_stack_size_was_set;
extern int smx_context_guard_size;
extern int smx_context_guard_size_was_set;
-/* *********************** */
-/* Context type definition */
-/* *********************** */
-/* the following function pointers types describe the interface that all context
- concepts must implement */
-/* each context type derive from this structure, so they must contain this structure
- * at their beginning -- OOP in C :/ */
-typedef struct s_smx_context {
- s_xbt_swag_hookup_t hookup;
- xbt_main_func_t code;
- void_pfn_smxprocess_t cleanup_func;
- smx_process_t process;
- char **argv;
- int argc;
- unsigned iwannadie:1;
-} s_smx_ctx_base_t;
-
-/* methods of this class */
-XBT_PUBLIC(void) smx_ctx_base_factory_init(smx_context_factory_t *factory);
-XBT_PUBLIC(int) smx_ctx_base_factory_finalize(smx_context_factory_t *factory);
-
-XBT_PUBLIC(smx_context_t)
-smx_ctx_base_factory_create_context_sized(size_t size, xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process);
-XBT_PUBLIC(void) smx_ctx_base_free(smx_context_t context);
-XBT_PUBLIC(void) smx_ctx_base_stop(smx_context_t context);
-XBT_PUBLIC(smx_context_t) smx_ctx_base_self(void);
-XBT_PUBLIC(smx_process_t) smx_ctx_base_get_process(smx_context_t context);
-
XBT_PUBLIC(xbt_dynar_t) SIMIX_process_get_runnable(void);
XBT_PUBLIC(smx_process_t) SIMIX_process_from_PID(int PID);
XBT_PUBLIC(xbt_dynar_t) SIMIX_processes_as_dynar(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_smxprocess_t function);
+XBT_PUBLIC(void) SIMIX_function_register_process_kill(void_pfn_smxprocess_t function);
/* Simulation execution */
XBT_PUBLIC(void) SIMIX_run(void);
/* Timer functions FIXME: should these be public? */
typedef struct s_smx_timer* smx_timer_t;
-XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, void *function, void *arg);
+XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, void (*function)(void*), void *arg);
XBT_PUBLIC(void) SIMIX_timer_remove(smx_timer_t timer);
XBT_PUBLIC(double) SIMIX_timer_next(void);
XBT_PUBLIC(double) SIMIX_timer_get_date(smx_timer_t timer);
/*********************************** Host *************************************/
XBT_PUBLIC(sg_host_t) SIMIX_host_self(void);
XBT_PUBLIC(const char*) SIMIX_host_self_get_name(void);
-#define SIMIX_host_get_name(h) sg_host_name(h) /* DEPRECATED: SIMIX_host_get_name */
+#define SIMIX_host_get_name(h) sg_host_get_name(h) /* DEPRECATED: SIMIX_host_get_name */
XBT_PUBLIC(void) SIMIX_host_on(sg_host_t host);
XBT_PUBLIC(void) SIMIX_host_off(sg_host_t host, smx_process_t issuer);
XBT_PUBLIC(void) SIMIX_host_self_set_data(void *data);
XBT_PUBLIC(int) SIMIX_process_has_pending_comms(smx_process_t process);
XBT_PUBLIC(void) SIMIX_process_on_exit_runall(smx_process_t process);
XBT_PUBLIC(void) SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void *data);
+ XBT_PUBLIC(xbt_main_func_t) SIMIX_process_get_code(void);
/****************************** Communication *********************************/
XBT_PUBLIC(void) SIMIX_comm_set_copy_data_callback(void (*callback) (smx_synchro_t, void*, size_t));
/******************************* Host simcalls ********************************/
/* TODO use handlers and keep sg_host_t hidden from higher levels */
-XBT_PUBLIC(const char *) simcall_host_get_name(sg_host_t host);
XBT_PUBLIC(xbt_dict_t) simcall_host_get_properties(sg_host_t host);
XBT_PUBLIC(void) simcall_host_on(sg_host_t host);
XBT_PUBLIC(void) simcall_host_off(sg_host_t host);
-XBT_PUBLIC(int) simcall_host_get_core(sg_host_t host);
XBT_PUBLIC(xbt_swag_t) simcall_host_get_process_list(sg_host_t host);
-XBT_PUBLIC(double) simcall_host_get_speed(sg_host_t host);
-XBT_PUBLIC(double) simcall_host_get_available_speed(sg_host_t host);
-/* Two possible states, 1 - CPU ON and 0 CPU OFF */
-XBT_PUBLIC(int) simcall_host_get_state(sg_host_t host);
-XBT_PUBLIC(void *) simcall_host_get_data(sg_host_t host);
XBT_PUBLIC(void) simcall_host_set_data(sg_host_t host, void *data);
XBT_PUBLIC(double) simcall_host_get_current_power_peak(sg_host_t host);
XBT_PUBLIC(double) simcall_host_get_power_peak_at(sg_host_t host, int pstate_index);
-XBT_PUBLIC(int) simcall_host_get_nb_pstates(sg_host_t host);
XBT_PUBLIC(void) simcall_host_set_pstate(sg_host_t host, int pstate_index);
-XBT_PUBLIC(int) simcall_host_get_pstate(sg_host_t host);
-XBT_PUBLIC(double) simcall_host_get_consumed_energy(sg_host_t host);
XBT_PUBLIC(double) simcall_host_get_wattmin_at(sg_host_t host, int pstate);
XBT_PUBLIC(double) simcall_host_get_wattmax_at(sg_host_t host, int pstate);
#define MPI_ROOT 0
#define MPI_INFO_NULL NULL
#define MPI_COMM_TYPE_SHARED 1
-#define MPI_WIN_NULL NULL
+#define MPI_WIN_NULL ((MPI_Win)NULL)
#define MPI_VERSION 1
#define MPI_SUBVERSION 1
// smpi functions
XBT_PUBLIC(int) smpi_global_size(void);
XBT_PUBLIC(MPI_Comm) smpi_process_comm_self(void);
+ XBT_PUBLIC(void*) smpi_process_get_user_data(void);
+ XBT_PUBLIC(void) smpi_process_set_user_data(void *);
/*
XBT_PUBLIC(void) smpi_exit(int);
*/
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <stdlib.h>
+#include "src/portable.h"
+#ifdef HAVE_SYS_PTRACE_H
+# include <sys/types.h>
+# include <sys/ptrace.h>
+#endif
#include "smx_private.h"
+#include "smx_private.hpp"
#include "xbt/heap.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/str.h"
#include "xbt/ex.h" /* ex_backtrace_display */
#include "mc/mc.h"
-#include "mc/mc_replay.h"
+#include "src/mc/mc_replay.h"
#include "simgrid/sg_config.h"
+#include "src/surf/callbacks.h"
+
#ifdef HAVE_MC
-#include "mc/mc_private.h"
-#include "mc/mc_protocol.h"
-#include "mc/mc_client.h"
+#include "src/mc/mc_private.h"
+#include "src/mc/mc_protocol.h"
+#include "src/mc/mc_client.h"
#endif
#ifdef HAVE_MC
#include <stdlib.h>
-#include "mc/mc_protocol.h"
+#include "src/mc/mc_protocol.h"
#endif
-#include "mc/mc_record.h"
+#include "src/mc/mc_record.h"
#ifdef HAVE_SMPI
-#include "smpi/private.h"
+#include "src/smpi/private.h"
#endif
XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
smx_global_t simix_global = NULL;
static xbt_heap_t simix_timers = NULL;
+/** @brief Timer datatype */
+typedef struct s_smx_timer {
+ double date;
+ void(* func)(void*);
+ void* args;
+} s_smx_timer_t;
+
+ void (*SMPI_switch_data_segment)(int) = NULL;
+
static void* SIMIX_synchro_mallocator_new_f(void);
static void SIMIX_synchro_mallocator_free_f(void* synchro);
static void SIMIX_synchro_mallocator_reset_f(void* synchro);
}
#endif
}
-#ifdef HAVE_MC
- if (MC_is_active()) {
- if (mc_stack) {
- MC_dump_stack_safety(mc_stack);
- }
- MC_print_statistics(mc_stats);
- }
-#endif
raise(signum);
}
#endif
/********************************* SIMIX **************************************/
-XBT_INLINE double SIMIX_timer_next(void)
+double SIMIX_timer_next(void)
{
return xbt_heap_size(simix_timers) > 0 ? xbt_heap_maxkey(simix_timers) : -1.0;
}
+static void kill_process(smx_process_t process)
+{
+ SIMIX_process_kill(process, NULL);
+}
+
+static void SIMIX_storage_create_(smx_storage_t storage)
+{
+ const char* key = xbt_dict_get_elm_key(storage);
+ SIMIX_storage_create(key, storage, NULL);
+}
+
/**
* \ingroup SIMIX_API
* \brief Initialize SIMIX internal data.
simix_global->registered_functions = xbt_dict_new_homogeneous(NULL);
simix_global->create_process_function = SIMIX_process_create;
- simix_global->kill_process_function = SIMIX_process_kill;
+ simix_global->kill_process_function = kill_process;
simix_global->cleanup_process_function = SIMIX_process_cleanup;
simix_global->synchro_mallocator = xbt_mallocator_new(65536,
SIMIX_synchro_mallocator_new_f, SIMIX_synchro_mallocator_free_f,
/* register a function to be called by SURF after the environment creation */
sg_platf_init();
sg_platf_postparse_add_cb(SIMIX_post_create_environment);
+ surf_on_host_created(SIMIX_host_create);
+ surf_on_storage_created(SIMIX_storage_create_);
}
if (!simix_timers) {
#ifdef HAVE_MC
// The communication initialization is done ASAP.
// We need to communicate initialization of the different layers to the model-checker.
- if (mc_mode == MC_MODE_NONE) {
- if (getenv(MC_ENV_SOCKET_FD)) {
- mc_mode = MC_MODE_CLIENT;
- MC_client_init();
- MC_client_hello();
- MC_client_handle_messages();
- }
- }
+ MC_client_init();
#endif
if (_sg_cfg_exit_asap)
*
* \return Return the clock.
*/
-XBT_INLINE double SIMIX_get_clock(void)
+double SIMIX_get_clock(void)
{
if(MC_is_active() || MC_record_replay_is_active()){
return MC_process_clock_get(SIMIX_process_self());
}
}
/* Wake up all processes waiting for a Surf action to finish */
- xbt_dynar_foreach(model_list, iter, model) {
+ xbt_dynar_foreach(all_existing_models, iter, model) {
XBT_DEBUG("Handling process whose action failed");
while ((action = surf_model_extract_failed_action_set(model))) {
XBT_DEBUG(" Handling Action %p",action);
while (xbt_heap_size(simix_timers) > 0 && SIMIX_get_clock() >= SIMIX_timer_next()) {
//FIXME: make the timers being real callbacks
// (i.e. provide dispatchers that read and expand the args)
- timer = xbt_heap_pop(simix_timers);
+ timer = (smx_timer_t) xbt_heap_pop(simix_timers);
if (timer->func)
- ((void (*)(void*))timer->func)(timer->args);
+ timer->func(timer->args);
xbt_free(timer);
}
/* Wake up all processes waiting for a Surf action to finish */
- xbt_dynar_foreach(model_list, iter, model) {
+ xbt_dynar_foreach(all_existing_models, iter, model) {
XBT_DEBUG("Handling process whose action failed");
while ((action = surf_model_extract_failed_action_set(model))) {
XBT_DEBUG(" Handling Action %p",action);
* \param arg Parameters of the function
*
*/
-XBT_INLINE smx_timer_t SIMIX_timer_set(double date, void *function, void *arg)
+smx_timer_t SIMIX_timer_set(double date, void (*function)(void*), void *arg)
{
smx_timer_t timer = xbt_new0(s_smx_timer_t, 1);
return timer;
}
/** @brief cancels a timer that was added earlier */
-XBT_INLINE void SIMIX_timer_remove(smx_timer_t timer) {
+void SIMIX_timer_remove(smx_timer_t timer) {
xbt_heap_rm_elm(simix_timers, timer, timer->date);
}
/** @brief Returns the date at which the timer will trigger (or 0 if NULL timer) */
-XBT_INLINE double SIMIX_timer_get_date(smx_timer_t timer) {
+double SIMIX_timer_get_date(smx_timer_t timer) {
return timer?timer->date:0;
}
* to call SIMIX_process_create().
* \param function create process function
*/
-XBT_INLINE void SIMIX_function_register_process_create(smx_creation_func_t
+void SIMIX_function_register_process_create(smx_creation_func_t
function)
{
simix_global->create_process_function = function;
*
* \param function Kill process function
*/
-XBT_INLINE void SIMIX_function_register_process_kill(void_pfn_smxprocess_t_smxprocess_t
+void SIMIX_function_register_process_kill(void_pfn_smxprocess_t
function)
{
simix_global->kill_process_function = function;
*
* \param function cleanup process function
*/
-XBT_INLINE void SIMIX_function_register_process_cleanup(void_pfn_smxprocess_t
+void SIMIX_function_register_process_cleanup(void_pfn_smxprocess_t
function)
{
simix_global->cleanup_process_function = function;
break;
}
XBT_INFO("Process %lu (%s@%s): waiting for %s synchro %p (%s) in state %d to finish",
- process->pid, process->name, sg_host_name(process->host),
+ process->pid, process->name, sg_host_get_name(process->host),
synchro_description, process->waiting_synchro,
process->waiting_synchro->name, (int)process->waiting_synchro->state);
}
else {
- XBT_INFO("Process %lu (%s@%s)", process->pid, process->name, sg_host_name(process->host));
+ XBT_INFO("Process %lu (%s@%s)", process->pid, process->name, sg_host_get_name(process->host));
}
}
}
}
xbt_dict_t SIMIX_asr_get_properties(const char *name)
{
- return xbt_lib_get_or_null(as_router_lib, name, ROUTING_PROP_ASR_LEVEL);
+ return (xbt_dict_t) xbt_lib_get_or_null(as_router_lib, name, ROUTING_PROP_ASR_LEVEL);
}
#include "xbt/log.h"
#include "xbt/dict.h"
#include "mc/mc.h"
-#include "mc/mc_replay.h"
-#include "mc/mc_client.h"
+#include "src/mc/mc_replay.h"
+#include "src/mc/mc_client.h"
+#include "src/simix/smx_private.hpp"
-#include "smpi/private.h"
+ #ifdef HAVE_SMPI
++#include "src/smpi/private.h"
+ #endif
+
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
"Logging specific to SIMIX (process)");
*
* \return The SIMIX process
*/
-XBT_INLINE smx_process_t SIMIX_process_self(void)
+smx_process_t SIMIX_process_self(void)
{
smx_context_t self_context = SIMIX_context_self();
/* cancel non-blocking communications */
smx_synchro_t synchro;
- while ((synchro = xbt_fifo_pop(process->comms))) {
+ while ((synchro = (smx_synchro_t) xbt_fifo_pop(process->comms))) {
/* make sure no one will finish the comm after this process is destroyed,
* because src_proc or dst_proc would be an invalid pointer */
{
smx_process_t process = NULL;
- while ((process = xbt_swag_extract(simix_global->process_to_destroy))) {
+ while ((process = (smx_process_t) xbt_swag_extract(simix_global->process_to_destroy))) {
XBT_DEBUG("Getting rid of %p",process);
SIMIX_context_free(process->context);
maestro->pid = simix_process_maxpid++;
maestro->ppid = -1;
maestro->name = (char *) "";
- maestro->running_ctx = xbt_new(xbt_running_ctx_t, 1);
+ maestro->running_ctx = (xbt_running_ctx_t*) xbt_malloc0(sizeof(xbt_running_ctx_t));
XBT_RUNNING_CTX_INITIALIZE(maestro->running_ctx);
maestro->context = SIMIX_context_new(NULL, 0, NULL, NULL, maestro);
maestro->simcall.issuer = maestro;
/* 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->host)) {
+ if (arg->auto_restart && !sg_host_get_state(arg->host)) {
SIMIX_host_add_auto_restart_process(arg->host,arg->name,arg->code, arg->data,
- sg_host_name(arg->host),
+ sg_host_get_name(arg->host),
SIMIX_timer_get_date(arg->kill_timer),
arg->argc,arg->argv,arg->properties,
arg->auto_restart);
}
- XBT_DEBUG("Process %s (%s) is dead",arg->name,sg_host_name(arg->host));
+ XBT_DEBUG("Process %s (%s) is dead",arg->name,sg_host_get_name(arg->host));
/* stop the context */
SIMIX_context_stop(arg->context);
}
kill_time, argc, argv, properties, auto_restart,
simcall->issuer);
}
+
+static void kill_process(void* process)
+{
+ simix_global->kill_process_function((smx_process_t) process);
+}
+
/**
* \brief Internal function to create a process.
*
XBT_DEBUG("Start process %s on host '%s'", name, hostname);
- if (!SIMIX_host_get_state(host)) {
+ if (!sg_host_get_state(host)) {
int i;
XBT_WARN("Cannot launch process '%s' on failed host '%s'", name,
hostname);
process->data = data;
process->comms = xbt_fifo_new();
process->simcall.issuer = process;
+ /* Initiliaze data segment to default value */
+ SIMIX_segment_index_set(process, -1);
- if (parent_process) {
+ if (parent_process != NULL) {
process->ppid = SIMIX_process_get_PID(parent_process);
+ /* SMPI process have their own data segment and
+ each other inherit from their father */
+ if(smpi_privatize_global_variables){
+ if( parent_process->pid != 0){
+ SIMIX_segment_index_set(process, parent_process->segment_index);
+ } else {
+ SIMIX_segment_index_set(process, process->pid - 1);
+ }
+ }
} else {
process->ppid = -1;
}
XBT_VERB("Create context %s", process->name);
process->context = SIMIX_context_new(code, argc, argv, simix_global->cleanup_process_function, process);
- process->running_ctx = xbt_new(xbt_running_ctx_t, 1);
+ process->running_ctx = (xbt_running_ctx_t*) xbt_malloc0(sizeof(xbt_running_ctx_t));
XBT_RUNNING_CTX_INITIALIZE(process->running_ctx);
if(MC_is_active()){
/* Now insert it in the global process list and in the process to run list */
xbt_swag_insert(process, simix_global->process_list);
- XBT_DEBUG("Inserting %s(%s) in the to_run list", process->name, sg_host_name(host));
+ XBT_DEBUG("Inserting %s(%s) in the to_run list", process->name, sg_host_get_name(host));
xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
if (kill_time > SIMIX_get_clock() && simix_global->kill_process_function) {
XBT_DEBUG("Process %s(%s) will be kill at time %f", process->name,
- sg_host_name(process->host), kill_time);
- process->kill_timer = SIMIX_timer_set(kill_time, simix_global->kill_process_function, process);
+ sg_host_get_name(process->host), kill_time);
+ process->kill_timer = SIMIX_timer_set(kill_time, kill_process, process);
}
}
return process;
*/
void SIMIX_process_kill(smx_process_t process, smx_process_t issuer) {
- XBT_DEBUG("Killing process %s on %s", process->name, sg_host_name(process->host));
+ XBT_DEBUG("Killing process %s on %s", process->name, sg_host_get_name(process->host));
process->context->iwannadie = 1;
process->blocked = 0;
{
smx_process_t p = NULL;
- while ((p = xbt_swag_extract(simix_global->process_list))) {
+ while ((p = (smx_process_t) xbt_swag_extract(simix_global->process_list))) {
if (p != issuer) {
SIMIX_process_kill(p,issuer);
}
return process->host;
}
+ xbt_main_func_t SIMIX_process_get_code(void){
+ return SIMIX_process_self()->code;
+ }
+
/* needs to be public and without simcall because it is called
by exceptions and logging events */
const char* SIMIX_process_self_get_name(void) {
surf_action_cancel(sync->sleep.surf_sleep);
smx_simcall_t simcall;
- while ((simcall = xbt_fifo_shift(sync->simcalls))) {
+ while ((simcall = (smx_simcall_t) xbt_fifo_shift(sync->simcalls))) {
simcall_process_sleep__set__result(simcall, SIMIX_DONE);
simcall->issuer->waiting_synchro = NULL;
if (simcall->issuer->suspended) {
smx_synchro_t SIMIX_process_sleep(smx_process_t process, double duration)
{
- smx_synchro_t synchro;
sg_host_t host = process->host;
/* check if the host is active */
if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
- sg_host_name(host));
+ sg_host_get_name(host));
}
- synchro = xbt_mallocator_get(simix_global->synchro_mallocator);
+ smx_synchro_t synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
synchro->type = SIMIX_SYNC_SLEEP;
synchro->name = NULL;
synchro->category = NULL;
e_smx_state_t state;
xbt_assert(synchro->type == SIMIX_SYNC_SLEEP || synchro->type == SIMIX_SYNC_JOIN);
- while ((simcall = xbt_fifo_shift(synchro->simcalls))) {
+ while ((simcall = (smx_simcall_t) xbt_fifo_shift(synchro->simcalls))) {
switch(surf_action_get_state(synchro->sleep.surf_sleep)){
case SURF_ACTION_FAILED:
SMX_THROW();
}
+ if(SMPI_switch_data_segment && self->segment_index != -1){
+ SMPI_switch_data_segment(self->segment_index);
+ }
}
/* callback: context fetching */
smx_process_t SIMIX_process_from_PID(int PID)
{
smx_process_t proc;
- xbt_swag_foreach(proc, simix_global->process_list)
- {
- if(proc->pid == PID)
- return proc;
+ xbt_swag_foreach(proc, simix_global->process_list) {
+ if (proc->pid == (unsigned long) PID)
+ return proc;
}
return NULL;
}
}
/** @brief 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, sg_host_name(process->host));
+ XBT_DEBUG("Restarting process %s on %s", process->name, sg_host_get_name(process->host));
//retrieve the arguments of the old process
//FIXME: Factorize this with SIMIX_host_add_auto_restart_process ?
s_smx_process_arg_t arg;
arg.code = process->code;
- arg.hostname = sg_host_name(process->host);
+ arg.hostname = sg_host_get_name(process->host);
arg.kill_time = SIMIX_timer_get_date(process->kill_timer);
arg.argc = process->argc;
arg.data = process->data;
}
return new_process;
}
+
+ void SIMIX_segment_index_set(smx_process_t proc, int index){
+ proc->segment_index = index;
+ }
#ifndef SMPI_PRIVATE_H
#define SMPI_PRIVATE_H
-#include "internal_config.h"
+#include "src/internal_config.h"
#include "xbt.h"
#include "xbt/base.h"
#include "xbt/xbt_os_time.h"
#include "xbt/synchro_core.h"
#include "simgrid/simix.h"
-#include "smpi/smpi_interface.h"
+#include "src/include/smpi/smpi_interface.h"
#include "smpi/smpi.h"
#include "smpi/smpi_cocci.h"
-#include "instr/instr_private.h"
+#include "src/instr/instr_private.h"
SG_BEGIN_DECL()
XBT_PRIVATE smpi_process_data_t smpi_process_data(void);
XBT_PRIVATE smpi_process_data_t smpi_process_remote_data(int index);
- XBT_PRIVATE void smpi_process_set_user_data(void *);
- XBT_PRIVATE void* smpi_process_get_user_data(void);
+ // smpi_process_[set/get]_user_data must be public
+ /* XBT_PRIVATE void smpi_process_set_user_data(void *); */
+ /* XBT_PRIVATE void* smpi_process_get_user_data(void); */
XBT_PRIVATE int smpi_process_count(void);
XBT_PRIVATE MPI_Comm smpi_process_comm_world(void);
XBT_PRIVATE MPI_Comm smpi_process_get_comm_intra(void);
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include "internal_config.h"
+#include "src/internal_config.h"
#include "private.h"
#include "xbt/dict.h"
#include "xbt/sysdep.h"
#include "surf/surf.h"
#include "simgrid/sg_config.h"
#include "simgrid/modelchecker.h"
-#include "mc/mc_replay.h"
+#include "src/mc/mc_replay.h"
#ifndef WIN32
#include <sys/mman.h>
#ifdef HAVE_PRIVATIZATION
int i;
if(smpi_loaded_page==-1){//initial switch, do the copy from the real page here
- for (i=0; i< SIMIX_process_count(); i++){
+ for (i=0; i< smpi_process_count(); i++){
memcpy(smpi_privatisation_regions[i].address,
TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
}
return strncmp("/dev/shm/my-buffer-", file, 19) == 0;
}
-void smpi_get_executable_global_size(){
- int size_bss_binary=0;
- int size_data_binary=0;
- FILE *fp;
- char *line = NULL; /* Temporal storage for each line that is readed */
- ssize_t read; /* Number of bytes readed */
- size_t n = 0; /* Amount of bytes to read by xbt_getline */
-
- char *lfields[7];
- int i, found = 0;
-
- char *command = bprintf("objdump --section-headers %s", xbt_binary_name);
-
- fp = popen(command, "r");
-
- if(fp == NULL){
- perror("popen failed");
- xbt_abort();
- }
-
- while ((read = xbt_getline(&line, &n, fp)) != -1 && found != 2) {
-
- if(n == 0)
- continue;
-
- /* Wipeout the new line character */
- line[read - 1] = '\0';
-
- lfields[0] = strtok(line, " ");
-
- if(lfields[0] == NULL)
- continue;
-
- if(strcmp(lfields[0], "Sections:") == 0
- || strcmp(lfields[0], "Idx") == 0
- || strncmp(lfields[0], xbt_binary_name, strlen(xbt_binary_name)) == 0)
- continue;
-
- for (i = 1; i < 7 && lfields[i - 1] != NULL; i++) {
- lfields[i] = strtok(NULL, " ");
- }
-
- /*
- * we are looking for these fields
- 23 .data 02625a20 00000000006013e0 00000000006013e0 000013e0 2**5
- CONTENTS, ALLOC, LOAD, DATA
- 24 .bss 02625a40 0000000002c26e00 0000000002c26e00 02626e00 2**5
- ALLOC
- */
-
- if(i>=6){
- if(strcmp(lfields[1], ".data") == 0){
- size_data_binary = strtoul(lfields[2], NULL, 16);
- smpi_start_data_exe = (char*) strtoul(lfields[4], NULL, 16);
- found++;
- }else if(strcmp(lfields[1], ".bss") == 0){
- //the beginning of bss is not exactly the end of data if not aligned, grow bss reported size accordingly
- //TODO : check if this is OK, as some segments may be inserted between them..
- size_bss_binary = ((char*) strtoul(lfields[4], NULL, 16) - (smpi_start_data_exe + size_data_binary))
- + strtoul(lfields[2], NULL, 16);
- found++;
- }
-
- }
-
- }
-
- smpi_size_data_exe = (unsigned long) smpi_start_data_exe
- - (unsigned long) TOPAGE(smpi_start_data_exe)
- + size_data_binary+size_bss_binary;
- xbt_free(command);
- xbt_free(line);
- pclose(fp);
-
-}
-
void smpi_initialize_global_memory_segments(){
#ifndef HAVE_PRIVATIZATION
smpi_privatisation_regions = (smpi_privatisation_region_t) malloc(
smpi_process_count() * sizeof(struct s_smpi_privatisation_region));
- for (i=0; i< SIMIX_process_count(); i++){
+ for (i=0; i< smpi_process_count(); i++){
//create SIMIX_process_count() mappings of this size with the same data inside
void *address = NULL;
char path[] = "/dev/shm/my-buffer-XXXXXX";
#include "private.h"
#include "smpi_mpi_dt_private.h"
#include "mc/mc.h"
-#include "mc/mc_record.h"
+#include "src/mc/mc_record.h"
#include "xbt/replay.h"
#include "surf/surf.h"
-#include "simix/smx_private.h"
+#include "src/simix/smx_private.h"
#include "simgrid/sg_config.h"
-#include "mc/mc_replay.h"
-#include "msg/msg_private.h"
+#include "src/mc/mc_replay.h"
++#include "src/msg/msg_private.h"
#include <float.h> /* DBL_MAX */
#include <stdint.h>
if (argc && argv) {
proc = SIMIX_process_self();
//FIXME: dirty cleanup method to avoid using msg cleanup functions on these processes when using MSG+SMPI
- proc->context->cleanup_func=SIMIX_process_cleanup;
+ SIMIX_process_set_cleanup_function(proc, SIMIX_process_cleanup);
char* instance_id = (*argv)[1];
int rank = atoi((*argv)[2]);
- index = smpi_process_index_of_smx_process(proc);
+ /* Now using segment index of the process */
+ index = proc->segment_index;
if(!index_to_process_data){
index_to_process_data=(int*)xbt_malloc(SIMIX_process_count()*sizeof(int));
}
+
+ if(smpi_privatize_global_variables){
+ /* Done at the process's creation */
+ SMPI_switch_data_segment(index);
+ }
+
MPI_Comm* temp_comm_world;
xbt_bar_t temp_bar;
smpi_deployment_register_process(instance_id, rank, index, &temp_comm_world ,&temp_bar);
data->index = index;
data->instance_id = instance_id;
data->replaying = 0;
- xbt_free(simcall_process_get_data(proc));
- simcall_process_set_data(proc, data);
+ //xbt_free(simcall_process_get_data(proc));
+
+ simdata_process_t simdata = simcall_process_get_data(proc);
+ simdata->data = data;
+
if (*argc > 3) {
free((*argv)[1]);
memmove(&(*argv)[0], &(*argv)[2], sizeof(char *) * (*argc - 2));
simcall_rdv_set_receiver(data->mailbox_small, proc);
XBT_DEBUG("<%d> New process in the game: %p", index, proc);
- if(smpi_privatize_global_variables){
- smpi_switch_data_segment(index);
- }
-
}
if (smpi_process_data() == NULL)
xbt_die("smpi_process_data() returned NULL. You probably gave a NULL parameter to MPI_Init. Although it's required by MPI-2, this is currently not supported by SMPI.");
*/
int smpi_process_initialized(void)
{
- int index = smpi_process_index();
- return ( (index != MPI_UNDEFINED)
- && (process_data[index_to_process_data[index]]->state == SMPI_INITIALIZED));
+ if (!index_to_process_data){
+ return false;
+ }
+ else{
+ int index = smpi_process_index();
+ return ( (index != MPI_UNDEFINED)
+ && (process_data[index_to_process_data[index]]->state == SMPI_INITIALIZED));
+ }
}
/**
smpi_process_data_t smpi_process_data(void)
{
- return SIMIX_process_self_get_data(SIMIX_process_self());
+ simdata_process_t simdata = SIMIX_process_self_get_data(SIMIX_process_self());
+ return simdata->data;
}
smpi_process_data_t smpi_process_remote_data(int index)
&& ((char*)buff < smpi_start_data_exe + smpi_size_data_exe )
){
XBT_DEBUG("Privatization : We are copying from a zone inside global memory... Saving data to temp buffer !");
- smpi_switch_data_segment(((smpi_process_data_t)SIMIX_process_get_data(comm->comm.src_proc))->index);
+ smpi_switch_data_segment(((smpi_process_data_t)(((simdata_process_t)SIMIX_process_get_data(comm->comm.src_proc))->data))->index);
tmpbuff = (void*)xbt_malloc(buff_size);
memcpy(tmpbuff, buff, buff_size);
}
&& ((char*)comm->comm.dst_buff < smpi_start_data_exe + smpi_size_data_exe )
){
XBT_DEBUG("Privatization : We are copying to a zone inside global memory - Switch data segment");
- smpi_switch_data_segment(((smpi_process_data_t)SIMIX_process_get_data(comm->comm.dst_proc))->index);
+ smpi_switch_data_segment(((smpi_process_data_t)(((simdata_process_t)SIMIX_process_get_data(comm->comm.dst_proc))->data))->index);
}
static void smpi_check_options(){
//check correctness of MPI parameters
- xbt_assert(sg_cfg_get_int("smpi/async_small_thres") <=
+ xbt_assert(sg_cfg_get_int("smpi/async_small_thresh") <=
sg_cfg_get_int("smpi/send_is_detached_thres"));
if (sg_cfg_is_default_value("smpi/running_power")) {
for (i = 0; i < process_count; i++) {
process_data[i] = xbt_new(s_smpi_process_data_t, 1);
//process_data[i]->index = i;
- process_data[i]->argc = NULL;
- process_data[i]->argv = NULL;
+ process_data[i]->argc = NULL;
+ process_data[i]->argv = NULL;
process_data[i]->mailbox = simcall_rdv_create(get_mailbox_name(name, i));
process_data[i]->mailbox_small =
simcall_rdv_create(get_mailbox_name_small(name, i));
- process_data[i]->mailboxes_mutex=xbt_mutex_init();
- process_data[i]->timer = xbt_os_timer_new();
+ process_data[i]->mailboxes_mutex = xbt_mutex_init();
+ process_data[i]->timer = xbt_os_timer_new();
if (MC_is_active())
MC_ignore_heap(process_data[i]->timer, xbt_os_timer_size());
- process_data[i]->comm_self = MPI_COMM_NULL;
- process_data[i]->comm_intra = MPI_COMM_NULL;
- process_data[i]->comm_world = NULL;
- process_data[i]->state = SMPI_UNINITIALIZED;
- process_data[i]->sampling = 0;
+ process_data[i]->comm_self = MPI_COMM_NULL;
+ process_data[i]->comm_intra = MPI_COMM_NULL;
+ process_data[i]->comm_world = NULL;
+ process_data[i]->state = SMPI_UNINITIALIZED;
+ process_data[i]->sampling = 0;
process_data[i]->finalization_barrier = NULL;
}
//if the process was launched through smpirun script
TRACE_add_end_function(TRACE_smpi_release);
SIMIX_global_init(&argc, argv);
+ MSG_init(&argc,argv);
+
+ SMPI_switch_data_segment = smpi_switch_data_segment;
smpi_init_options();
int PMPI_Init(int *argc, char ***argv)
{
- smpi_process_init(argc, argv);
- smpi_process_mark_as_initialized();
- int rank = smpi_process_index();
- TRACE_smpi_init(rank);
- TRACE_smpi_computing_init(rank);
- instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
- extra->type = TRACING_INIT;
- TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
- TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
- smpi_bench_begin();
+ // PMPI_Init is call only one time by only by SMPI process
+ int already_init;
+ MPI_Initialized(&already_init);
+ if(!(already_init)){
+ smpi_process_init(argc, argv);
+ smpi_process_mark_as_initialized();
+ int rank = smpi_process_index();
+ TRACE_smpi_init(rank);
+ TRACE_smpi_computing_init(rank);
+ instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
+ extra->type = TRACING_INIT;
+ TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
+ TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+ smpi_bench_begin();
+ }
return MPI_SUCCESS;
}
int dt_size_recv = 1;
if(!known)
dt_size_recv = smpi_datatype_size(recvtype);
+ if((smpi_comm_rank(comm)==root)){
extra->recvcounts= xbt_malloc(size*sizeof(int));
for(i=0; i< size; i++)//copy data to avoid bad free
extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
-
+ }
TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts,
int dt_size_send = 1;
if(!known)
dt_size_send = smpi_datatype_size(sendtype);
+ if((smpi_comm_rank(comm)==root)){
extra->sendcounts= xbt_malloc(size*sizeof(int));
for(i=0; i< size; i++)//copy data to avoid bad free
extra->sendcounts[i] = sendcounts[i]*dt_size_send;
+ }
extra->datatype2 = encode_datatype(recvtype, &known);
int dt_size_recv = 1;
if(!known)