Пример #1
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;
}
Пример #2
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);
}
Пример #3
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);
}