Esempio n. 1
0
/** \ingroup msg_mailbox_management
 * \brief Set the mailbox to receive in asynchronous mode
 *
 * All messages sent to this mailbox will be transferred to 
 * the receiver without waiting for the receive call. 
 * The receive call will still be necessary to use the received data.
 * If there is a need to receive some messages asynchronously, and some not, 
 * two different mailboxes should be used.
 *
 * \param alias The name of the mailbox 
 */
void MSG_mailbox_set_async(const char *alias){
  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);

  simcall_rdv_set_receiver(mailbox, SIMIX_process_self());
  XBT_VERB("%s mailbox set to receive eagerly for process %p\n",alias, SIMIX_process_self());

}
Esempio n. 2
0
CommPtr Mailbox::put_init()
{
  CommPtr res   = CommPtr(new s4u::Comm());
  res->sender_  = SIMIX_process_self();
  res->mailbox_ = this;
  return res;
}
Esempio n. 3
0
Host *Host::current(){
	smx_process_t smx_proc = SIMIX_process_self();
	if (smx_proc == NULL)
		xbt_die("Cannot call Host::current() from the maestro context");

	return Host::byName(SIMIX_host_get_name(SIMIX_process_get_host(smx_proc)));
}
Esempio n. 4
0
/**
 * \brief Cleans the MSG data of a process.
 * \param smx_proc a SIMIX process
 */
void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc)
{
  simdata_process_t msg_proc;

  // get the MSG process from the SIMIX process
  if (smx_proc == SIMIX_process_self()) {
    /* avoid a SIMIX request if this function is called by the process itself */
    msg_proc = SIMIX_process_self_get_data(smx_proc);
    SIMIX_process_self_set_data(smx_proc, NULL);
  }
  else {
    msg_proc = simcall_process_get_data(smx_proc);
    simcall_process_set_data(smx_proc, NULL);
  }

#ifdef HAVE_TRACING
  TRACE_msg_process_end(smx_proc);
#endif
  // free the data if a function was provided
  if (msg_proc->data && msg_global->process_data_cleanup) {
    msg_global->process_data_cleanup(msg_proc->data);
  }

  // remove the process from its virtual machine
  if (msg_proc->vm) {
    int pos = xbt_dynar_search(msg_proc->vm->processes,&smx_proc);
    xbt_dynar_remove_at(msg_proc->vm->processes,pos, NULL);
  }

  // free the MSG process
  xbt_free(msg_proc);
}
Esempio n. 5
0
static void smx_ctx_cojava_suspend(smx_context_t context)
{
  smx_context_t previous_context = context;
  unsigned long int i = cojava_process_index++;
  jobject next_coroutine;

  if (i < xbt_dynar_length(cojava_processes)) {
    smx_context_t next_context = SIMIX_process_get_context(xbt_dynar_get_as(
    cojava_processes,i, smx_process_t));
    my_current_context = next_context;
    XBT_DEBUG("Switching to %p",my_current_context);
    smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(next_context);
    if (!java_context->jprocess) {
      java_context->super.code(java_context->super.argc, java_context->super.argv);
      smx_ctx_cojava_create_coroutine(java_context);
    }
    else if (!java_context->bound) {
      java_context->bound = 1;
      smx_process_t process = SIMIX_process_self();
      (*global_env)->SetLongField(global_env, java_context->jprocess,
                                  jprocess_field_Process_bind,
                                  (intptr_t)process);
    }

    next_coroutine = java_context->jcoroutine;
  }
  else {
    //Give maestro the control back.
    next_coroutine = cojava_maestro_coroutine;
    my_current_context = maestro_context;
  }
  (*global_env)->CallStaticVoidMethod(global_env, coclass, coroutine_yieldTo, next_coroutine);
  my_current_context = previous_context;
}
Esempio n. 6
0
/**
 * \brief Cleans the MSG data of a process.
 * \param smx_proc a SIMIX process
 */
void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc)
{
  simdata_process_t msg_proc;

  // get the MSG process from the SIMIX process
  if (smx_proc == SIMIX_process_self()) {
    /* avoid a SIMIX request if this function is called by the process itself */
    msg_proc = SIMIX_process_self_get_data(smx_proc);
    SIMIX_process_self_set_data(smx_proc, NULL);
  }
  else {
    msg_proc = simcall_process_get_data(smx_proc);
    simcall_process_set_data(smx_proc, NULL);
  }

  TRACE_msg_process_end(smx_proc);
  // free the data if a function was provided
  if (msg_proc && msg_proc->data && msg_global->process_data_cleanup) {
    msg_global->process_data_cleanup(msg_proc->data);
  }

  // free the MSG process
  xbt_free(msg_proc);
  SIMIX_process_cleanup(smx_proc);
}
Esempio n. 7
0
/* Internal function used to factorize code between
 * MSG_task_isend_with_matching() and MSG_task_dsend().
 */
static XBT_INLINE
msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias,
                                   int (*match_fun)(void*,void*, smx_synchro_t),
                                   void *match_data, void_f_pvoid_t cleanup,
                                   int detached)
{
  simdata_task_t t_simdata = NULL;
  msg_process_t process = MSG_process_self();
  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
  int call_end = TRACE_msg_task_put_start(task);

  /* Prepare the task to send */
  t_simdata = task->simdata;
  t_simdata->sender = process;
  t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host;

  if (t_simdata->isused != 0) {
    if (msg_global->debug_multiple_use){
      XBT_ERROR("This task is already used in there:");
      xbt_backtrace_display(t_simdata->isused);
      XBT_ERROR("And you try to reuse it from here:");
      xbt_backtrace_display_current();
    } else {
      xbt_assert(t_simdata->isused == 0,
                 "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/debug_multiple_use:on to get the backtrace of the other process)");
    }
  }

  if (msg_global->debug_multiple_use)
    MSG_BT(t_simdata->isused, "Using Backtrace");
  else
    t_simdata->isused = (void*)1;
  t_simdata->comm = NULL;
  msg_global->sent_msg++;

  /* Send it by calling SIMIX network layer */
  smx_synchro_t act = simcall_comm_isend(SIMIX_process_self(), mailbox, t_simdata->bytes_amount,
                                        t_simdata->rate, task, sizeof(void *),
                                        match_fun, cleanup, NULL, match_data,detached);
  t_simdata->comm = act; /* FIXME: is the field t_simdata->comm still useful? */

  msg_comm_t comm;
  if (detached) {
    comm = NULL;
  } else {
    comm = xbt_new0(s_msg_comm_t, 1);
    comm->task_sent = task;
    comm->task_received = NULL;
    comm->status = MSG_OK;
    comm->s_comm = act;
  }

  if (TRACE_is_enabled())
    simcall_set_category(act, task->category);
  if (call_end)
    TRACE_msg_task_put_end();

  return comm;
}
Esempio n. 8
0
const char *TRACE_internal_smpi_get_category (void)
{
  if (!TRACE_smpi_is_enabled()) return NULL;

  char processid[INSTR_DEFAULT_STR_SIZE];
  snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
  return xbt_dict_get_or_null (process_category, processid);
}
Esempio n. 9
0
/**
 * \ingroup simix_process_management
 * \brief Return the name of an agent.
 *
 * This functions checks whether \a process is a valid pointer or not and return its name.
 * \param process SIMIX process
 * \return The process name
 */
const char* simcall_process_get_name(smx_process_t process)
{
  if (process == SIMIX_process_self()) {
    /* avoid a simcall if this function is called by the process itself */
    return process->name;
  }
  return simcall_BODY_process_get_name(process);
}
Esempio n. 10
0
/**
 * \ingroup simix_process_management
 * \brief Return the user data of a #smx_process_t.
 * \param process a SIMIX process
 * \return the user data of this process
 */
void* simcall_process_get_data(smx_process_t process)
{
  if (process == SIMIX_process_self()) {
    /* avoid a simcall if this function is called by the process itself */
    return SIMIX_process_get_data(process);
  }

  return simcall_BODY_process_get_data(process);
}
Esempio n. 11
0
void smpi_process_init(int *argc, char ***argv)
{
  int index=-1;
  smpi_process_data_t data;
  smx_process_t proc;

  if (argc && argv) {
    proc = SIMIX_process_self();
    //FIXME: dirty cleanup method to avoid using msg cleanup functions on these processes when using MSG+SMPI
    SIMIX_process_set_cleanup_function(proc, MSG_process_cleanup_from_SIMIX);
    char* instance_id = (*argv)[1];
    int rank = xbt_str_parse_int((*argv)[2], "Invalid rank: %s");
    index = smpi_process_index_of_smx_process(proc);

    if(!index_to_process_data){
      index_to_process_data=(int*)xbt_malloc(SIMIX_process_count()*sizeof(int));
    }

    if(smpi_privatize_global_variables){
      /* Now using segment index of the process  */
      index = proc->segment_index;
      /* 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              = smpi_process_remote_data(index);
    data->comm_world  = temp_comm_world;
    if(temp_bar != NULL) data->finalization_barrier = temp_bar;
    data->index       = index;
    data->instance_id = instance_id;
    data->replaying   = 0;
    //xbt_free(simcall_process_get_data(proc));

    simdata_process_t simdata = static_cast<simdata_process_t>(simcall_process_get_data(proc));
    simdata->data             = data;

    if (*argc > 3) {
      free((*argv)[1]);
      memmove(&(*argv)[0], &(*argv)[2], sizeof(char *) * (*argc - 2));
      (*argv)[(*argc) - 1] = NULL;
      (*argv)[(*argc) - 2] = NULL;
    }
    (*argc)-=2;
    data->argc = argc;
    data->argv = argv;
    // set the process attached to the mailbox
    simcall_mbox_set_receiver(data->mailbox_small, proc);
    XBT_DEBUG("<%d> New process in the game: %p", index, proc);
  }
  xbt_assert(smpi_process_data(),
      "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.");
}
Esempio n. 12
0
/**
 * \ingroup simix_process_management
 * \brief Set the user data of a #smx_process_t.
 *
 * This functions sets the user data associated to \a process.
 * \param process SIMIX process
 * \param data User data
 */
void simcall_process_set_data(smx_process_t process, void *data)
{
  if (process == SIMIX_process_self()) {
    /* avoid a simcall if this function is called by the process itself */
    SIMIX_process_self_set_data(process, data);
  }
  else {
    simcall_BODY_process_set_data(process, data);
  }
}
Esempio n. 13
0
/** \ingroup m_process_management
 * \brief Return the location on which a process is running.
 * \param process a process (NULL means the current one)
 * \return the msg_host_t corresponding to the location on which \a
 * process is running.
 */
msg_host_t MSG_process_get_host(msg_process_t process)
{
  simdata_process_t simdata;
  if (process == NULL) {
    simdata = SIMIX_process_self_get_data(SIMIX_process_self());
  }
  else {
    simdata = simcall_process_get_data(process);
  }
  return simdata->m_host;
}
Esempio n. 14
0
inline static R simcall(e_smx_simcall_t call, T const&... t)
{
  smx_actor_t self = SIMIX_process_self();
  simgrid::simix::marshal(&self->simcall, call, t...);
  if (self != simix_global->maestro_process) {
    XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name.c_str(),
              SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
    SIMIX_process_yield(self);
  } else {
    SIMIX_simcall_handle(&self->simcall, 0);
  }
  return simgrid::simix::unmarshal<R>(self->simcall.result);
}
Esempio n. 15
0
/** Run the Java org.simgrid.msg.Process */
void java_main_jprocess(jobject jprocess)
{
  JNIEnv *env = get_current_thread_env();
  simgrid::java::JavaContext* context = (simgrid::java::JavaContext*) SIMIX_context_self();
  context->jprocess = jprocess;
  smx_process_t process = SIMIX_process_self();
  jprocess_bind(context->jprocess, process, env);

  // Adrien, ugly path, just to bypass creation of context at low levels (i.e such as for the VM migration for instance)
  if (context->jprocess == nullptr)
    return;
  else
    run_jprocess(env, context->jprocess);
}
Esempio n. 16
0
void TRACE_internal_smpi_set_category (const char *category)
{
  if (!TRACE_smpi_is_enabled()) return;

  //declare category
  TRACE_category (category);

  char processid[INSTR_DEFAULT_STR_SIZE];
  snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
  if (xbt_dict_get_or_null (process_category, processid))
    xbt_dict_remove (process_category, processid);
  if (category != NULL)
    xbt_dict_set (process_category, processid, xbt_strdup(category), NULL);
}
Esempio n. 17
0
/**
 * \brief Return the name of an agent.
 *
 * This functions checks whether \a process is a valid pointer or not and return its name.
 * \param process SIMIX process
 * \return The process name
 */
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;
  req->process_get_name.process = process;
  SIMIX_request_push();
  return req->process_get_name.result;
}
Esempio n. 18
0
/**
 * \brief Return the user data of a #smx_process_t.
 *
 * This functions checks whether \a process is a valid pointer or not and return the user data associated to \a process if it is possible.
 * \param process SIMIX process
 * \return A void pointer to the user data
 */
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;
  req->process_get_data.process = process;
  SIMIX_request_push();
  return req->process_get_data.result;
}
Esempio n. 19
0
/**
 * \brief Set the user data of a #m_process_t.
 *
 * This functions checks whether \a process is a valid pointer or not and set the user data associated to \a process if it is possible.
 * \param process SIMIX process
 * \param data User data
 */
void SIMIX_req_process_set_data(smx_process_t process, void *data)
{
  if (process == SIMIX_process_self()) {
    /* avoid a request if this function is called by the process itself */
    SIMIX_process_self_set_data(data);
  }
  else {

    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();
  }
}
Esempio n. 20
0
static void smx_ctx_cojava_resume(smx_context_t new_context) {
  my_current_context = new_context;
  smx_ctx_cojava_t java_context = (smx_ctx_cojava_t)(new_context);

  if (!java_context->jprocess) {
    java_context->super.code(java_context->super.argc, java_context->super.argv);
    smx_ctx_cojava_create_coroutine(java_context);
    java_context->bound = 1;
  }
  else if (!java_context->bound) {
    java_context->bound = 1;
    smx_process_t process = SIMIX_process_self();
    (*global_env)->SetLongField(global_env, java_context->jprocess,
                                jprocess_field_Process_bind, (intptr_t)process);
  }
  (*global_env)->CallStaticVoidMethod(global_env, coclass, coroutine_yieldTo, java_context->jcoroutine);
}
Esempio n. 21
0
/******************************** Process ************************************/
void MSG_process_cleanup_from_SIMIX(smx_process_t smx_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 */
    msg_proc = SIMIX_process_self_get_data();
  }
  else {
    msg_proc = SIMIX_req_process_get_data(smx_proc);
  }

#ifdef HAVE_TRACING
  TRACE_msg_process_end(smx_proc);
#endif

  xbt_free(msg_proc);
}
Esempio n. 22
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;
}
Esempio n. 23
0
xbt_thread_t xbt_thread_create(const char *name, void_f_pvoid_t code,
                               void *param, int joinable)
{
  xbt_thread_t res = xbt_new0(s_xbt_thread_t, 1);
  res->name = xbt_strdup(name);
  res->userparam = param;
  res->code = code;
  res->father_data = SIMIX_process_self_get_data(SIMIX_process_self());
  /*   char*name = bprintf("%s#%p",SIMIX_process_self_get_name(), param); */
  simcall_process_create(&res->s_process, name,
                           xbt_thread_create_wrapper, res,
                           SIMIX_host_self_get_name(), -1.0, 0, NULL,
                           /*props */ NULL,0);
  res->joinable = joinable;
  res->done = 0;
  res->cond = xbt_cond_init();
  res->mutex = xbt_mutex_init();
  //   free(name);
  return res;
}
Esempio n. 24
0
static int xbt_thread_create_wrapper(int argc, char *argv[])
{
  smx_process_t self = SIMIX_process_self();
  xbt_thread_t t =
      (xbt_thread_t) SIMIX_process_self_get_data(self);
  simcall_process_set_data(self, t->father_data);
  t->code(t->userparam);
  if (t->joinable) {
    t->done = 1;
    xbt_mutex_acquire(t->mutex);
    xbt_cond_broadcast(t->cond);
    xbt_mutex_release(t->mutex);
  } else {
    xbt_mutex_destroy(t->mutex);
    xbt_cond_destroy(t->cond);
    free(t->name);
    free(t);
  }
  return 0;
}
Esempio n. 25
0
/* Internal function used to factorize code between MSG_task_isend_with_matching() and MSG_task_dsend(). */
static inline msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias,
                                                     int (*match_fun)(void*,void*, smx_synchro_t),
                                                     void *match_data, void_f_pvoid_t cleanup, int detached)
{
  simdata_task_t t_simdata = nullptr;
  msg_process_t process = MSG_process_self();
  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
  int call_end = TRACE_msg_task_put_start(task);

  /* Prepare the task to send */
  t_simdata = task->simdata;
  t_simdata->sender = process;
  t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data())->m_host;
  t_simdata->setUsed();
  t_simdata->comm = nullptr;
  msg_global->sent_msg++;

  /* Send it by calling SIMIX network layer */
  smx_synchro_t act = simcall_comm_isend(SIMIX_process_self(), mailbox, t_simdata->bytes_amount, t_simdata->rate,
                                         task, sizeof(void *), match_fun, cleanup, nullptr, match_data,detached);
  t_simdata->comm = static_cast<simgrid::simix::Comm*>(act); /* FIXME: is the field t_simdata->comm still useful? */

  msg_comm_t comm;
  if (detached) {
    comm = nullptr;
  } else {
    comm = xbt_new0(s_msg_comm_t, 1);
    comm->task_sent = task;
    comm->task_received = nullptr;
    comm->status = MSG_OK;
    comm->s_comm = act;
  }

  if (TRACE_is_enabled())
    simcall_set_category(act, task->category);
  if (call_end)
    TRACE_msg_task_put_end();

  return comm;
}
Esempio n. 26
0
void SIMIX_request_push()
{
  xbt_swag_t req_table;
  smx_process_t issuer = SIMIX_process_self();

  if (issuer != simix_global->maestro_process){
    issuer->request.issuer = issuer;
    req_table = SIMIX_request_get_reqlist(SIMIX_context_get_thread_id());

    xbt_swag_insert_at_tail(&issuer->request, req_table);

    XBT_DEBUG("Pushed request %s (%d) of %s",
        SIMIX_request_name(issuer->request.call), issuer->request.call,
        issuer->name);

    XBT_DEBUG("Yield process '%s' on request of type %s (%d)", issuer->name,
        SIMIX_request_name(issuer->request.call), issuer->request.call);
    SIMIX_process_yield();
  } else {
    SIMIX_request_pre(&issuer->request, 0);
  }
}
Esempio n. 27
0
/**
 * \brief Cleans the MSG data of a process.
 * \param smx_proc a SIMIX process
 */
void MSG_process_cleanup_from_SIMIX(smx_actor_t smx_proc)
{
  simdata_process_t msg_proc;

  // get the MSG process from the SIMIX process
  if (smx_proc == SIMIX_process_self()) {
    /* avoid a SIMIX request if this function is called by the process itself */
    msg_proc = (simdata_process_t) SIMIX_process_self_get_data();
    SIMIX_process_self_set_data(nullptr);
  } else {
    msg_proc = (simdata_process_t) simcall_process_get_data(smx_proc);
    simcall_process_set_data(smx_proc, nullptr);
  }

  TRACE_msg_process_destroy(smx_proc->name.c_str(), smx_proc->pid);
  // free the data if a function was provided
  if (msg_proc && msg_proc->data && msg_global->process_data_cleanup) {
    msg_global->process_data_cleanup(msg_proc->data);
  }

  // free the MSG process
  xbt_free(msg_proc);
  SIMIX_process_cleanup(smx_proc);
}
Esempio n. 28
0
void xbt_thread_yield(void)
{
  SIMIX_process_yield(SIMIX_process_self());
}
Esempio n. 29
0
xbt_thread_t xbt_thread_self(void)
{
  return SIMIX_process_self_get_data(SIMIX_process_self());
}
Esempio n. 30
0
void xbt_thread_exit()
{
  simcall_process_kill(SIMIX_process_self());
}