/*
 * Instrumentation functions to trace MSG processes (msg_process_t)
 */
void TRACE_msg_process_change_host(msg_process_t process, msg_host_t old_host, msg_host_t new_host)
{
  if (TRACE_msg_process_is_enabled()){
    static long long int counter = 0;

    char key[INSTR_DEFAULT_STR_SIZE];
    snprintf (key, INSTR_DEFAULT_STR_SIZE, "%lld", counter++);

    int len = INSTR_DEFAULT_STR_SIZE;
    char str[INSTR_DEFAULT_STR_SIZE];

    //start link
    container_t msg = PJ_container_get (instr_process_id(process, str, len));
    type_t type = PJ_type_get ("MSG_PROCESS_LINK", PJ_type_get_root());
    new_pajeStartLink (MSG_get_clock(), PJ_container_get_root(), type, msg, "M", key);

    //destroy existing container of this process
    TRACE_msg_process_destroy (MSG_process_get_name (process), MSG_process_get_PID (process));

    //create new container on the new_host location
    TRACE_msg_process_create (MSG_process_get_name (process), MSG_process_get_PID (process), new_host);

    //end link
    msg = PJ_container_get(instr_process_id(process, str, len));
    type = PJ_type_get ("MSG_PROCESS_LINK", PJ_type_get_root());
    new_pajeEndLink (MSG_get_clock(), PJ_container_get_root(), type, msg, "M", key);
  }
}
Exemple #2
0
/** \ingroup m_process_management
 * \brief Creates and runs a new #m_process_t.

 * A constructor for #m_process_t taking four arguments and returning the
 * corresponding object. The structure (and the corresponding thread) is
 * created, and put in the list of ready process.
 * \param name a name for the object. It is for user-level information
   and can be NULL.
 * \param code is a function describing the behavior of the agent. It
   should then only use functions described in \ref
   m_process_management (to create a new #m_process_t for example),
   in \ref m_host_management (only the read-only functions i.e. whose
   name contains the word get), in \ref m_task_management (to create
   or destroy some #m_task_t for example) and in \ref
   msg_gos_functions (to handle file transfers and task processing).
 * \param data a pointer to any data one may want to attach to the new
   object.  It is for user-level information and can be NULL. It can
   be retrieved with the function \ref MSG_process_get_data.
 * \param host the location where the new agent is executed.
 * \param argc first argument passed to \a code
 * \param argv second argument passed to \a code
 * \param properties list a properties defined for this process
 * \see m_process_t
 * \return The new corresponding object.
 */
m_process_t MSG_process_create_with_environment(const char *name,
                                                xbt_main_func_t code,
                                                void *data, m_host_t host,
                                                int argc, char **argv,
                                                xbt_dict_t properties)
{
  xbt_assert(code != NULL && host != NULL, "Invalid parameters");
  simdata_process_t simdata = xbt_new0(s_simdata_process_t, 1);
  m_process_t process;

  /* 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(MSG_process_self());
  } else {
    simdata->PPID = -1;
  }

  /* 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(&process, name, code, simdata, host->name,
                           argc, argv, properties);

#ifdef HAVE_TRACING
  TRACE_msg_process_create(process);
#endif

  if (!process) {
    /* Undo everything we have just changed */
    msg_global->PID--;
    xbt_free(simdata);
    return NULL;
  }

  return process;
}
Exemple #3
0
/** \ingroup m_process_management
 * \brief Creates and runs a new #msg_process_t.

 * A constructor for #msg_process_t taking four arguments and returning the
 * corresponding object. The structure (and the corresponding thread) is
 * created, and put in the list of ready process.
 * \param name a name for the object. It is for user-level information
   and can be NULL.
 * \param code is a function describing the behavior of the process. It
   should then only use functions described in \ref
   m_process_management (to create a new #msg_process_t for example),
   in \ref m_host_management (only the read-only functions i.e. whose
   name contains the word get), in \ref m_task_management (to create
   or destroy some #msg_task_t for example) and in \ref
   msg_task_usage (to handle file transfers and task processing).
 * \param data a pointer to any data one may want to attach to the new
   object.  It is for user-level information and can be NULL. It can
   be retrieved with the function \ref MSG_process_get_data.
 * \param host the location where the new process is executed.
 * \param argc first argument passed to \a code
 * \param argv second argument passed to \a code. WARNING, these strings are freed by the SimGrid kernel when the process exits, so they cannot be static nor shared between several processes.
 * \param properties list a properties defined for this process
 * \see msg_process_t
 * \return The new corresponding object.
 */
msg_process_t MSG_process_create_with_environment(const char *name,
                                                xbt_main_func_t code,
                                                void *data, msg_host_t host,
                                                int argc, char **argv,
                                                xbt_dict_t properties)
{
  xbt_assert(code != NULL && host != NULL, "Invalid parameters");
  simdata_process_t simdata = xbt_new0(s_simdata_process_t, 1);
  msg_process_t process;

  /* Simulator data for MSG */
  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;

  /* Let's create the process: SIMIX may decide to start it right now,
   * even before returning the flow control to us */
 simcall_process_create(&process, name, code, simdata, sg_host_name(host), -1,
                           argc, argv, properties,0);

  #ifdef HAVE_TRACING
    TRACE_msg_process_create(name, simcall_process_get_PID(process), simdata->m_host);
  #endif

  if (!process) {
    /* Undo everything we have just changed */
    xbt_free(simdata);
    return NULL;
  }
  else {
    #ifdef HAVE_TRACING
    simcall_process_on_exit(process,(int_f_pvoid_t)TRACE_msg_process_kill,MSG_process_self());
    #endif
  }
  return process;
}