X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/6badbbf58554a35b03f58509b0b18cf606c38f5e..7bac600c529ba83f8f246a2dcfa9ddd9c0095675:/src/simix/smx_process.cpp diff --git a/src/simix/smx_process.cpp b/src/simix/smx_process.cpp index c939390546..46007fbaaa 100644 --- a/src/simix/smx_process.cpp +++ b/src/simix/smx_process.cpp @@ -4,6 +4,7 @@ /* 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 "src/surf/surf_interface.hpp" #include "smx_private.h" #include "xbt/sysdep.h" #include "xbt/log.h" @@ -12,6 +13,7 @@ #include "src/mc/mc_replay.h" #include "src/mc/mc_client.h" #include "src/simix/smx_private.hpp" +#include "src/msg/msg_private.h" #ifdef HAVE_SMPI #include "src/smpi/private.h" @@ -57,7 +59,7 @@ void SIMIX_process_cleanup(smx_process_t process) /* Unregister from the kill timer if any */ if (process->kill_timer != NULL) - SIMIX_timer_remove(process->kill_timer); + SIMIX_timer_remove(process->kill_timer); xbt_os_mutex_acquire(simix_global->mutex); @@ -101,7 +103,8 @@ void SIMIX_process_cleanup(smx_process_t process) XBT_DEBUG("%p should not be run anymore",process); xbt_swag_remove(process, simix_global->process_list); - xbt_swag_remove(process, sg_host_simix(process->host)->process_list); + if (process->host) + xbt_swag_remove(process, sg_host_simix(process->host)->process_list); xbt_swag_insert(process, simix_global->process_to_destroy); process->context->iwannadie = 0; @@ -136,25 +139,45 @@ void SIMIX_process_empty_trash(void) } } -/** - * \brief Creates and runs the maestro process - */ -void SIMIX_create_maestro_process() +namespace simgrid { +namespace simix { + +void create_maestro(std::function code) { smx_process_t maestro = NULL; - /* Create maestro process and intilialize it */ maestro = xbt_new0(s_smx_process_t, 1); maestro->pid = simix_process_maxpid++; maestro->ppid = -1; - maestro->name = (char *) ""; + maestro->name = (char*) ""; + maestro->data = nullptr; 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); + + if (!code) { + maestro->context = SIMIX_context_new(NULL, 0, nullptr, NULL, maestro); + } else { + if (!simix_global) + xbt_die("simix is not initialized, please call MSG_init first"); + maestro->context = + simix_global->context_factory->create_maestro(code, maestro); + } + maestro->simcall.issuer = maestro; simix_global->maestro_process = maestro; - return; } + +} +} + +/** + * \brief Creates and runs the maestro process + */ +void SIMIX_maestro_create(void (*code)(void*), void* data) +{ + simgrid::simix::create_maestro(std::bind(code, data)); +} + /** * \brief Stops a process. * @@ -166,7 +189,7 @@ void SIMIX_process_stop(smx_process_t arg) { /* execute the on_exit functions */ SIMIX_process_on_exit_runall(arg); /* Add the process to the list of process to restart, only if the host is down */ - if (arg->auto_restart && arg->host->isOff()) { + if (arg->auto_restart && arg->host->is_off()) { SIMIX_host_add_auto_restart_process(arg->host,arg->name,arg->code, arg->data, sg_host_get_name(arg->host), SIMIX_timer_get_date(arg->kill_timer), @@ -245,7 +268,7 @@ smx_process_t SIMIX_process_create( XBT_DEBUG("Start process %s on host '%s'", name, hostname); - if (host->isOff()) { + if (host->is_off()) { int i; XBT_WARN("Cannot launch process '%s' on failed host '%s'", name, hostname); @@ -319,10 +342,117 @@ smx_process_t SIMIX_process_create( sg_host_get_name(process->host), kill_time); process->kill_timer = SIMIX_timer_set(kill_time, kill_process, process); } + + /* Tracing the process creation */ + TRACE_msg_process_create(process->name, process->pid, process->host); } return process; } +smx_process_t SIMIX_process_attach( + const char* name, + void *data, + const char* hostname, + xbt_dict_t properties, + smx_process_t parent_process) +{ + // This is mostly a copy/paste from SIMIX_process_new(), + // it'd be nice to share some code between those two functions. + + sg_host_t host = sg_host_by_name(hostname); + XBT_DEBUG("Attach process %s on host '%s'", name, hostname); + + if (host->is_off()) { + XBT_WARN("Cannot launch process '%s' on failed host '%s'", + name, hostname); + return nullptr; + } + + smx_process_t process = xbt_new0(s_smx_process_t, 1); + /* Process data */ + process->pid = simix_process_maxpid++; + process->name = xbt_strdup(name); + process->host = host; + process->data = data; + process->comms = xbt_fifo_new(); + process->simcall.issuer = process; + process->ppid = -1; + /* Initiliaze data segment to default value */ + SIMIX_segment_index_set(process, -1); + 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 */ + #ifdef HAVE_SMPI + 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); + } + } + #endif + } + + /* Process data for auto-restart */ + process->auto_restart = false; + process->code = nullptr; + process->argc = 0; + process->argv = nullptr; + + XBT_VERB("Create context %s", process->name); + if (!simix_global) + xbt_die("simix is not initialized, please call MSG_init first"); + process->context = simix_global->context_factory->attach( + simix_global->cleanup_process_function, process); + + 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()){ + MC_ignore_heap(process->running_ctx, sizeof(*process->running_ctx)); + } + + /* Add properties */ + process->properties = properties; + + /* Add the process to it's host process list */ + xbt_swag_insert(process, sg_host_simix(host)->process_list); + + /* 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_get_name(host)); + xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process); + + /* Tracing the process creation */ + TRACE_msg_process_create(process->name, process->pid, process->host); + + auto context = dynamic_cast(process->context); + if (!context) + xbt_die("Not a suitable context"); + + context->attach_start(); + return process; +} + +void SIMIX_process_detach(void) +{ + auto context = dynamic_cast(SIMIX_context_self()); + if (!context) + xbt_die("Not a suitable context"); + + simix_global->cleanup_process_function(context->process()); + + // Let maestro ignore we are still alive: + // xbt_swag_remove(context->process(), simix_global->process_list); + + // TODDO, Remove from proces list: + // xbt_swag_remove(process, sg_host_simix(host)->process_list); + + context->attach_stop(); + // delete context; +} + /** * \brief Executes the processes from simix_global->process_to_run. * @@ -370,7 +500,7 @@ void SIMIX_process_kill(smx_process_t process, smx_process_t issuer) { case SIMIX_SYNC_EXECUTE: case SIMIX_SYNC_PARALLEL_EXECUTE: - SIMIX_process_execution_destroy(process->waiting_synchro); + SIMIX_execution_destroy(process->waiting_synchro); break; case SIMIX_SYNC_COMMUNICATE: @@ -427,7 +557,7 @@ void SIMIX_process_throw(smx_process_t process, xbt_errcat_t cat, int value, con case SIMIX_SYNC_EXECUTE: case SIMIX_SYNC_PARALLEL_EXECUTE: - SIMIX_process_execution_cancel(process->waiting_synchro); + SIMIX_execution_cancel(process->waiting_synchro); break; case SIMIX_SYNC_COMMUNICATE: @@ -507,7 +637,7 @@ void simcall_HANDLER_process_suspend(smx_simcall_t simcall, smx_process_t proces } else { xbt_fifo_push(sync_suspend->simcalls, simcall); process->waiting_synchro = sync_suspend; - SIMIX_host_execution_suspend(process->waiting_synchro); + SIMIX_execution_suspend(process->waiting_synchro); } /* If we are suspending ourselves, then just do not finish the simcall now */ } @@ -533,7 +663,7 @@ smx_synchro_t SIMIX_process_suspend(smx_process_t process, smx_process_t issuer) case SIMIX_SYNC_EXECUTE: case SIMIX_SYNC_PARALLEL_EXECUTE: - SIMIX_host_execution_suspend(process->waiting_synchro); + SIMIX_execution_suspend(process->waiting_synchro); break; case SIMIX_SYNC_COMMUNICATE: @@ -559,7 +689,7 @@ smx_synchro_t SIMIX_process_suspend(smx_process_t process, smx_process_t issuer) } } else { /* FIXME: computation size is zero. Is it okay that bound is zero ? */ - return SIMIX_process_execute(process, "suspend", 0.0, 1.0, 0.0, 0); + return SIMIX_execution_start(process, "suspend", 0.0, 1.0, 0.0, 0); } } @@ -589,7 +719,7 @@ void SIMIX_process_resume(smx_process_t process, smx_process_t issuer) case SIMIX_SYNC_EXECUTE: case SIMIX_SYNC_PARALLEL_EXECUTE: - SIMIX_host_execution_resume(process->waiting_synchro); + SIMIX_execution_resume(process->waiting_synchro); break; case SIMIX_SYNC_COMMUNICATE: @@ -680,7 +810,7 @@ const char* SIMIX_process_self_get_name(void) { smx_process_t process = SIMIX_process_self(); if (process == NULL || process == simix_global->maestro_process) - return ""; + return "maestro"; return SIMIX_process_get_name(process); } @@ -721,7 +851,7 @@ void simcall_HANDLER_process_join(smx_simcall_t simcall, smx_process_t process, static int SIMIX_process_join_finish(smx_process_exit_status_t status, smx_synchro_t sync){ if (sync->sleep.surf_sleep) { - surf_action_cancel(sync->sleep.surf_sleep); + sync->sleep.surf_sleep->cancel(); smx_simcall_t simcall; while ((simcall = (smx_simcall_t) xbt_fifo_shift(sync->simcalls))) { @@ -735,7 +865,7 @@ static int SIMIX_process_join_finish(smx_process_exit_status_t status, smx_synch SIMIX_simcall_answer(simcall); } } - surf_action_unref(sync->sleep.surf_sleep); + sync->sleep.surf_sleep->unref(); sync->sleep.surf_sleep = NULL; } xbt_mallocator_release(simix_global->synchro_mallocator, sync); @@ -768,7 +898,7 @@ smx_synchro_t SIMIX_process_sleep(smx_process_t process, double duration) sg_host_t host = process->host; /* check if the host is active */ - if (host->isOff()) { + if (host->is_off()) { THROWF(host_error, 0, "Host %s failed, you cannot call this function", sg_host_get_name(host)); } @@ -781,7 +911,7 @@ smx_synchro_t SIMIX_process_sleep(smx_process_t process, double duration) synchro->sleep.host = host; synchro->sleep.surf_sleep = surf_host_sleep(host, duration); - surf_action_set_data(synchro->sleep.surf_sleep, synchro); + synchro->sleep.surf_sleep->setData(synchro); XBT_DEBUG("Create sleep synchronization %p", synchro); return synchro; @@ -795,7 +925,7 @@ void SIMIX_post_process_sleep(smx_synchro_t synchro) while ((simcall = (smx_simcall_t) xbt_fifo_shift(synchro->simcalls))) { - switch(surf_action_get_state(synchro->sleep.surf_sleep)){ + switch (synchro->sleep.surf_sleep->getState()){ case SURF_ACTION_FAILED: simcall->issuer->context->iwannadie = 1; //SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed"); @@ -810,7 +940,7 @@ void SIMIX_post_process_sleep(smx_synchro_t synchro) THROW_IMPOSSIBLE; break; } - if (simcall->issuer->host->isOff()) { + if (simcall->issuer->host->is_off()) { simcall->issuer->context->iwannadie = 1; } simcall_process_sleep__set__result(simcall, state); @@ -833,7 +963,7 @@ void SIMIX_process_sleep_destroy(smx_synchro_t synchro) xbt_assert(synchro->type == SIMIX_SYNC_SLEEP || synchro->type == SIMIX_SYNC_JOIN); if (synchro->sleep.surf_sleep) { - surf_action_unref(synchro->sleep.surf_sleep); + synchro->sleep.surf_sleep->unref(); synchro->sleep.surf_sleep = NULL; } if (synchro->type == SIMIX_SYNC_SLEEP) @@ -843,14 +973,14 @@ void SIMIX_process_sleep_destroy(smx_synchro_t synchro) void SIMIX_process_sleep_suspend(smx_synchro_t synchro) { xbt_assert(synchro->type == SIMIX_SYNC_SLEEP); - surf_action_suspend(synchro->sleep.surf_sleep); + synchro->sleep.surf_sleep->suspend(); } void SIMIX_process_sleep_resume(smx_synchro_t synchro) { XBT_DEBUG("Synchro state is %d on process_sleep_resume.", synchro->state); xbt_assert(synchro->type == SIMIX_SYNC_SLEEP); - surf_action_resume(synchro->sleep.surf_sleep); + synchro->sleep.surf_sleep->resume(); } /** @@ -902,7 +1032,11 @@ void SIMIX_process_yield(smx_process_t self) /* callback: context fetching */ xbt_running_ctx_t *SIMIX_process_get_running_context(void) { - return SIMIX_process_self()->running_ctx; + smx_process_t process = SIMIX_process_self(); + if (process) + return process->running_ctx; + else + return nullptr; } /* callback: termination */