Ejemplo 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());

}
Ejemplo n.º 2
0
/** \ingroup msg_task_usage
 * \brief Receives a task from a mailbox from a specific host with a given timeout.
 *
 * This is a blocking function with a timeout, the execution flow will be blocked
 * until the task is received or the timeout is achieved. See #MSG_task_irecv
 * for receiving tasks asynchronously. You can provide a -1 timeout
 * to obtain an infinite timeout.
 *
 * \param task a memory location for storing a #msg_task_t.
 * \param alias name of the mailbox to receive the task from
 * \param timeout is the maximum wait time for completion (provide -1 for no timeout)
 * \param host a #msg_host_t host from where the task was sent
 *
 * \return Returns
 * #MSG_OK if the task was successfully received,
* #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
 */
msg_error_t
MSG_task_receive_ext(msg_task_t * task, const char *alias, double timeout,
                     msg_host_t host)
{
  xbt_ex_t e;
  msg_error_t ret = MSG_OK;
  XBT_DEBUG
      ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'",
       alias);
  TRY {
    ret = MSG_mailbox_get_task_ext(MSG_mailbox_get_by_alias(alias), task,
                                   host, timeout);
  }
  CATCH(e) {
    switch (e.category) {
    case cancel_error:          /* may be thrown by MSG_mailbox_get_by_alias */
      ret = MSG_HOST_FAILURE;
      break;
    default:
      RETHROW;
    }
    xbt_ex_free(e);
  }
  return ret;
}
Ejemplo 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;
}
Ejemplo n.º 4
0
/** \ingroup msg_task_usage
 * \brief Receives a task from a mailbox from a specific host with a given timeout
 *  and at a given rate.
 *
 * \param task a memory location for storing a #msg_task_t.
 * \param alias name of the mailbox to receive the task from
 * \param timeout is the maximum wait time for completion (provide -1 for no timeout)
 * \param host a #msg_host_t host from where the task was sent
 * \param rate limit the reception to rate bandwidth
 *
 * \return Returns
 * #MSG_OK if the task was successfully received,
* #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
 */
msg_error_t
MSG_task_receive_ext_bounded(msg_task_t * task, const char *alias, double timeout,
                             msg_host_t host, double rate)
{
  XBT_DEBUG
      ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'",
       alias);
  return MSG_mailbox_get_task_ext_bounded(MSG_mailbox_get_by_alias(alias), task,
                                          host, timeout, rate);
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
/** \ingroup msg_task_usage
 * \brief Starts listening for receiving a task from an asynchronous communication at a given rate.
 *
 * \param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication.
 * \param name of the mailbox to receive the task on
 * \param rate limit the bandwidth to the given rate
 * \return the msg_comm_t communication created
 */
msg_comm_t MSG_task_irecv_bounded(msg_task_t *task, const char *name, double rate)
{
  smx_mailbox_t rdv = MSG_mailbox_get_by_alias(name);

  /* FIXME: these functions are not traceable */
  /* Sanity check */
  xbt_assert(task, "Null pointer for the task storage");

  if (*task)
    XBT_CRITICAL("MSG_task_irecv() was asked to write in a non empty task struct.");

  /* Try to receive it by calling SIMIX network layer */
  msg_comm_t comm = xbt_new0(s_msg_comm_t, 1);
  comm->task_sent = nullptr;
  comm->task_received = task;
  comm->status = MSG_OK;
  comm->s_comm = simcall_comm_irecv(MSG_process_self(), rdv, task, nullptr, nullptr, nullptr, nullptr, rate);

  return comm;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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
}