Esempio n. 1
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. 2
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. 3
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. 4
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. 5
0
/** \ingroup m_process_management
 * \brief Return the location on which a process is running.
 * \param process a process (nullptr 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 == nullptr) {
    simdata = (simdata_process_t) SIMIX_process_self_get_data();
  }
  else {
    simdata = (simdata_process_t) simcall_process_get_data(process);
  }
  return simdata ? simdata->m_host : nullptr;
}
Esempio n. 6
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. 7
0
/** \ingroup msg_task_usage
 * \brief Sends a task on a mailbox, with support for matching requests
 *
 * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test()
 * to end the communication.
 *
 * \param task a #msg_task_t to send on another location.
 * \param alias name of the mailbox to sent the task to
 * \param match_fun boolean function which parameters are:
 *        - match_data_provided_here
 *        - match_data_provided_by_other_side_if_any
 *        - the_smx_action_describing_the_other_side
 * \param match_data user provided data passed to match_fun
 * \return the msg_comm_t communication created
 */
XBT_INLINE msg_comm_t MSG_task_isend_with_matching(msg_task_t task, const char *alias,
    int (*match_fun)(void*,void*, smx_action_t),
    void *match_data)
{
  simdata_task_t t_simdata = NULL;
  msg_process_t process = MSG_process_self();
  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);

#ifdef HAVE_TRACING
  int call_end = TRACE_msg_task_put_start(task);
#endif

  /* 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;

  xbt_assert(t_simdata->isused == 0,
              "This task is still being used somewhere else. You cannot send it now. Go fix your code!");

  t_simdata->isused = 1;
  t_simdata->comm = NULL;
  msg_global->sent_msg++;

  /* Send it by calling SIMIX network layer */
  msg_comm_t comm = xbt_new0(s_msg_comm_t, 1);
  comm->task_sent = task;
  comm->task_received = NULL;
  comm->status = MSG_OK;
  comm->s_comm =
    simcall_comm_isend(mailbox, t_simdata->message_size,
                         t_simdata->rate, task, sizeof(void *), match_fun, NULL, match_data, 0);
  t_simdata->comm = comm->s_comm; /* FIXME: is the field t_simdata->comm still useful? */
#ifdef HAVE_TRACING
    if (TRACE_is_enabled()) {
      simcall_set_category(comm->s_comm, task->category);
    }
#endif

#ifdef HAVE_TRACING
  if (call_end)
    TRACE_msg_task_put_end();
#endif

  return comm;
}
Esempio n. 8
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. 9
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. 10
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. 11
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. 12
0
/** \ingroup msg_task_usage
 * \brief Sends a task on a mailbox with a maximal rate.
 *
 * This is a non blocking detached send function.
 * Think of it as a best effort send. Keep in mind that the third parameter
 * is only called if the communication fails. If the communication does work,
 * it is responsibility of the receiver code to free anything related to
 * the task, as usual. More details on this can be obtained on
 * <a href="http://lists.gforge.inria.fr/pipermail/simgrid-user/2011-November/002649.html">this thread</a>
 * in the SimGrid-user mailing list archive.
 *
 * \param task a #msg_task_t to send on another location.
 * \param alias name of the mailbox to sent the task to
 * \param cleanup a function to destroy the task if the
 * communication fails, e.g. MSG_task_destroy
 * (if NULL, no function will be called)
 * \param maxrate the maximum communication rate for sending this task
 * 
 */
void MSG_task_dsend_bounded(msg_task_t task, const char *alias, void_f_pvoid_t cleanup, double maxrate)
{
  task->simdata->rate = maxrate;
  
  simdata_task_t t_simdata = NULL;
  msg_process_t process = MSG_process_self();
  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);

  /* 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;

  xbt_assert(t_simdata->isused == 0,
              "This task is still being used somewhere else. You cannot send it now. Go fix your code!");

  t_simdata->isused = 1;
  t_simdata->comm = NULL;
  msg_global->sent_msg++;

#ifdef HAVE_TRACING
  int call_end = TRACE_msg_task_put_start(task);
#endif

  /* Send it by calling SIMIX network layer */
  smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size,
                       t_simdata->rate, task, sizeof(void *), NULL, cleanup, NULL, 1);
  t_simdata->comm = comm;
#ifdef HAVE_TRACING
    if (TRACE_is_enabled()) {
      simcall_set_category(comm, task->category);
    }
#endif

#ifdef HAVE_TRACING
  if (call_end)
    TRACE_msg_task_put_end();
#endif
}
Esempio n. 13
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. 14
0
xbt_thread_t xbt_thread_self(void)
{
  return SIMIX_process_self_get_data(SIMIX_process_self());
}
Esempio n. 15
0
msg_error_t
MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task,
                             double timeout)
{
  xbt_ex_t e;
  msg_error_t ret = MSG_OK;
  simdata_task_t t_simdata = NULL;
  msg_process_t process = MSG_process_self();
  simdata_process_t p_simdata = SIMIX_process_self_get_data(process);

#ifdef HAVE_TRACING
  int call_end = TRACE_msg_task_put_start(task);    //must be after CHECK_HOST()
#endif

  /* 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;

  xbt_assert(t_simdata->isused == 0,
              "This task is still being used somewhere else. You cannot send it now. Go fix your code!");

  t_simdata->isused=1;
  t_simdata->comm = NULL;
  msg_global->sent_msg++;


  p_simdata->waiting_task = task;

  /* Try to send it by calling SIMIX network layer */
  TRY {
      smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size,
                                  t_simdata->rate, task, sizeof(void *),
                                  NULL, NULL, task, 0);
#ifdef HAVE_TRACING
    if (TRACE_is_enabled()) {
      simcall_set_category(comm, task->category);
    }
#endif
     t_simdata->comm = comm;
     simcall_comm_wait(comm, timeout);
  }

  CATCH(e) {
    switch (e.category) {
    case network_error:
      ret = MSG_TRANSFER_FAILURE;
      break;
    case timeout_error:
      ret = MSG_TIMEOUT;
      break;
    default:
      RETHROW;
    }
    xbt_ex_free(e);

    /* If the send failed, it is not used anymore */
    t_simdata->isused = 0;
  }


  p_simdata->waiting_task = NULL;
#ifdef HAVE_TRACING
  if (call_end)
    TRACE_msg_task_put_end();
#endif
  MSG_RETURN(ret);
}
Esempio n. 16
0
smpi_process_data_t smpi_process_data(void)
{
  simdata_process_t simdata = static_cast<simdata_process_t>(SIMIX_process_self_get_data());
  return static_cast<smpi_process_data_t>(simdata->data);
}
Esempio n. 17
0
/** \ingroup msg_task_usage
 * \brief Executes a parallel task and waits for its termination.
 *
 * \param task a #msg_task_t to execute on the location on which the process is running.
 *
 * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED
 * or #MSG_HOST_FAILURE otherwise
 */
msg_error_t MSG_parallel_task_execute(msg_task_t task)
{
  xbt_ex_t e;
  simdata_task_t simdata = task->simdata;
  msg_process_t self = SIMIX_process_self();
  simdata_process_t p_simdata = SIMIX_process_self_get_data(self);
  e_smx_state_t comp_state;
  msg_error_t status = MSG_OK;

  TRACE_msg_task_execute_start(task);

  xbt_assert((!simdata->compute) && (task->simdata->isused == 0),
             "This task is executed somewhere else. Go fix your code! %d",
             task->simdata->isused!=NULL);

  XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self()));

  if (simdata->flops_amount == 0 && !simdata->host_nb) {
    TRACE_msg_task_execute_end(task);
    return MSG_OK;
  }


  TRY {
    if (msg_global->debug_multiple_use)
      MSG_BT(simdata->isused, "Using Backtrace");
    else
      simdata->isused = (void*)1;

    if (simdata->host_nb > 0) {
      simdata->compute = simcall_process_parallel_execute(task->name,
                                                       simdata->host_nb,
                                                       simdata->host_list,
                                                       simdata->flops_parallel_amount,
                                                       simdata->bytes_parallel_amount,
                                                       1.0, -1.0);
      XBT_DEBUG("Parallel execution action created: %p", simdata->compute);
    } else {
      unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host, sizeof(msg_host_t));
      XBT_DEBUG("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask);

      simdata->compute = simcall_process_execute(task->name,
                                              simdata->flops_amount,
                                              simdata->priority,
                                              simdata->bound,
                                              affinity_mask
                                              );

    }
    simcall_set_category(simdata->compute, task->category);
    p_simdata->waiting_action = simdata->compute;
    comp_state = simcall_process_execution_wait(simdata->compute);

    p_simdata->waiting_action = NULL;

    if (msg_global->debug_multiple_use && simdata->isused!=0)
      xbt_ex_free(*(xbt_ex_t*)simdata->isused);
    simdata->isused = 0;

    XBT_DEBUG("Execution task '%s' finished in state %d",
              task->name, (int)comp_state);
  }
  CATCH(e) {
    switch (e.category) {
    case cancel_error:
      status = MSG_TASK_CANCELED;
      break;
    case host_error:
      status = MSG_HOST_FAILURE;
      break;
    default:
      RETHROW;
    }
    xbt_ex_free(e);
  }
  /* action ended, set comm and compute = NULL, the actions is already destroyed
   * in the main function */
  simdata->flops_amount = 0.0;
  simdata->comm = NULL;
  simdata->compute = NULL;
  TRACE_msg_task_execute_end(task);

  MSG_RETURN(status);
}
Esempio n. 18
0
/** \ingroup msg_task_usage
 * \brief Executes a parallel task and waits for its termination.
 *
 * \param task a #msg_task_t to execute on the location on which the process is running.
 *
 * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED
 * or #MSG_HOST_FAILURE otherwise
 */
msg_error_t MSG_parallel_task_execute(msg_task_t task)
{
  simdata_task_t simdata = task->simdata;
  simdata_process_t p_simdata = (simdata_process_t) SIMIX_process_self_get_data();
  e_smx_state_t comp_state;
  msg_error_t status = MSG_OK;

  TRACE_msg_task_execute_start(task);

  xbt_assert((!simdata->compute) && !task->simdata->isused,
             "This task is executed somewhere else. Go fix your code!");

  XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self()));

  if (simdata->flops_amount == 0 && !simdata->host_nb) {
    TRACE_msg_task_execute_end(task);
    return MSG_OK;
  }

  try {
    simdata->setUsed();

    if (simdata->host_nb > 0) {
      simdata->compute = static_cast<simgrid::simix::Exec*>(
          simcall_execution_parallel_start(task->name, simdata->host_nb,simdata->host_list,
                                                       simdata->flops_parallel_amount, simdata->bytes_parallel_amount,
                                                       1.0, -1.0));
      XBT_DEBUG("Parallel execution action created: %p", simdata->compute);
    } else {
      unsigned long affinity_mask =
         (unsigned long)(uintptr_t) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host,
                                                             sizeof(msg_host_t));
      XBT_DEBUG("execute %s@%s with affinity(0x%04lx)",
                MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask);

          simdata->compute = static_cast<simgrid::simix::Exec*>(
              simcall_execution_start(task->name, simdata->flops_amount, simdata->priority,
                                                 simdata->bound, affinity_mask));
    }
    simcall_set_category(simdata->compute, task->category);
    p_simdata->waiting_action = simdata->compute;
    comp_state = simcall_execution_wait(simdata->compute);

    p_simdata->waiting_action = nullptr;
    simdata->setNotUsed();

    XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state);
  }
  catch (xbt_ex& e) {
    switch (e.category) {
    case cancel_error:
      status = MSG_TASK_CANCELED;
      break;
    case host_error:
      status = MSG_HOST_FAILURE;
      break;
    default:
      throw;
    }
  }

  /* action ended, set comm and compute = nullptr, the actions is already destroyed in the main function */
  simdata->flops_amount = 0.0;
  simdata->comm = nullptr;
  simdata->compute = nullptr;
  TRACE_msg_task_execute_end(task);

  MSG_RETURN(status);
}
Esempio n. 19
0
msg_error_t
MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task,
                             double timeout)
{
  msg_error_t ret = MSG_OK;
  simdata_task_t t_simdata = NULL;
  msg_process_t process = MSG_process_self();
  simdata_process_t p_simdata = SIMIX_process_self_get_data(process);

  int call_end = TRACE_msg_task_put_start(task);    //must be after CHECK_HOST()

  /* 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++;


  p_simdata->waiting_task = task;

  xbt_ex_t e;
  /* Try to send it by calling SIMIX network layer */
  TRY {
    smx_synchro_t comm = NULL; /* MC needs the comm to be set to NULL during the simix call  */
    comm = simcall_comm_isend(SIMIX_process_self(), mailbox,t_simdata->bytes_amount,
                                  t_simdata->rate, task, sizeof(void *),
                                  NULL, NULL, NULL, task, 0);
    if (TRACE_is_enabled())
      simcall_set_category(comm, task->category);
     t_simdata->comm = comm;
     simcall_comm_wait(comm, timeout);
  }

  CATCH(e) {
    switch (e.category) {
    case cancel_error:
      ret = MSG_HOST_FAILURE;
      break;
    case network_error:
      ret = MSG_TRANSFER_FAILURE;
      break;
    case timeout_error:
      ret = MSG_TIMEOUT;
      break;
    default:
      RETHROW;
    }
    xbt_ex_free(e);

    /* If the send failed, it is not used anymore */
    if (msg_global->debug_multiple_use && t_simdata->isused!=0)
      xbt_ex_free(*(xbt_ex_t*)t_simdata->isused);
    t_simdata->isused = 0;
  }


  p_simdata->waiting_task = NULL;
  if (call_end)
    TRACE_msg_task_put_end();
  MSG_RETURN(ret);
}
Esempio n. 20
0
smpi_process_data_t smpi_process_data(void)
{
  return SIMIX_process_self_get_data(SIMIX_process_self());
}
Esempio n. 21
0
/** \ingroup msg_task_usage
 * \brief Executes a parallel task and waits for its termination.
 *
 * \param task a #msg_task_t to execute on the location on which the process is running.
 *
 * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED
 * or #MSG_HOST_FAILURE otherwise
 */
msg_error_t MSG_parallel_task_execute(msg_task_t task)
{
  xbt_ex_t e;
  simdata_task_t simdata = task->simdata;
  msg_process_t self = SIMIX_process_self();
  simdata_process_t p_simdata = SIMIX_process_self_get_data(self);
  e_smx_state_t comp_state;
  msg_error_t status = MSG_OK;

#ifdef HAVE_TRACING
  TRACE_msg_task_execute_start(task);
#endif

  xbt_assert((!simdata->compute) && (task->simdata->isused == 0),
             "This task is executed somewhere else. Go fix your code! %d",
             task->simdata->isused);

  XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self()));

  if (simdata->computation_amount == 0 && !simdata->host_nb) {
#ifdef HAVE_TRACING
    TRACE_msg_task_execute_end(task);
#endif
    return MSG_OK;
  }


  TRY {

    simdata->isused=1;

    if (simdata->host_nb > 0) {
      simdata->compute = simcall_host_parallel_execute(task->name,
                                                       simdata->host_nb,
                                                       simdata->host_list,
                                                       simdata->comp_amount,
                                                       simdata->comm_amount,
                                                       1.0, -1.0);
      XBT_DEBUG("Parallel execution action created: %p", simdata->compute);
    } else {
      simdata->compute = simcall_host_execute(task->name,
                                              p_simdata->m_host,
                                              simdata->computation_amount,
                                              simdata->priority);

    }
#ifdef HAVE_TRACING
    simcall_set_category(simdata->compute, task->category);
#endif
    p_simdata->waiting_action = simdata->compute;
    comp_state = simcall_host_execution_wait(simdata->compute);

    p_simdata->waiting_action = NULL;

    simdata->isused=0;

    XBT_DEBUG("Execution task '%s' finished in state %d",
              task->name, (int)comp_state);
  }
  CATCH(e) {
    switch (e.category) {
    case cancel_error:
      status = MSG_TASK_CANCELED;
      break;
    default:
      RETHROW;
    }
    xbt_ex_free(e);
  }
  /* action ended, set comm and compute = NULL, the actions is already destroyed
   * in the main function */
  simdata->computation_amount = 0.0;
  simdata->comm = NULL;
  simdata->compute = NULL;
#ifdef HAVE_TRACING
  TRACE_msg_task_execute_end(task);
#endif

  MSG_RETURN(status);
}