Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
21192878cffe617881ead7e9c566382b2fc1082c
[simgrid.git] / src / msg / msg_mailbox.cpp
1 /* Mailboxes in MSG */
2
3 /* Copyright (c) 2008-2015. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include <xbt/ex.hpp>
10
11 #include "simgrid/msg.h"
12 #include "msg_private.h"
13 #include "simgrid/s4u/mailbox.hpp"
14
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_mailbox, msg, "Logging specific to MSG (mailbox)");
16
17 int MSG_mailbox_is_empty(msg_mailbox_t mailbox)
18 {
19   return mailbox->empty();
20 }
21
22 msg_task_t MSG_mailbox_front(msg_mailbox_t mailbox)
23 {
24   simgrid::kernel::activity::Comm* comm = static_cast<simgrid::kernel::activity::Comm*>(simcall_mbox_front(mailbox->getImpl()));
25
26   if (!comm)
27     return nullptr;
28
29   return (msg_task_t) comm->src_data;
30 }
31
32 msg_mailbox_t MSG_mailbox_get_by_alias(const char *alias)
33 {
34   return simgrid::s4u::Mailbox::byName(alias);
35 }
36
37 /** \ingroup msg_mailbox_management
38  * \brief Set the mailbox to receive in asynchronous mode
39  *
40  * All messages sent to this mailbox will be transferred to the receiver without waiting for the receive call.
41  * The receive call will still be necessary to use the received data.
42  * If there is a need to receive some messages asynchronously, and some not, two different mailboxes should be used.
43  *
44  * \param alias The name of the mailbox
45  */
46 void MSG_mailbox_set_async(const char *alias){
47   msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
48
49   simcall_mbox_set_receiver(mailbox->getImpl(), SIMIX_process_self());
50   XBT_VERB("%s mailbox set to receive eagerly for myself\n",alias);
51 }
52
53 /** \ingroup msg_mailbox_management
54  * \brief Get a task from a mailbox on a given host
55  *
56  * \param mailbox The mailbox where the task was sent
57  * \param task a memory location for storing a #msg_task_t.
58  * \param host a #msg_host_t host from where the task was sent
59  * \param timeout a timeout
60
61  * \return Returns
62  * #MSG_OK if the task was successfully received,
63  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
64  */
65 msg_error_t MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, msg_task_t *task, msg_host_t host, double timeout)
66 {
67   return MSG_mailbox_get_task_ext_bounded(mailbox, task, host, timeout, -1.0);
68 }
69
70 /** \ingroup msg_mailbox_management
71  * \brief Get a task from a mailbox on a given host at a given rate
72  *
73  * \param mailbox The mailbox where the task was sent
74  * \param task a memory location for storing a #msg_task_t.
75  * \param host a #msg_host_t host from where the task was sent
76  * \param timeout a timeout
77  * \param rate a rate
78
79  * \return Returns
80  * #MSG_OK if the task was successfully received,
81  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
82  */
83 msg_error_t MSG_mailbox_get_task_ext_bounded(msg_mailbox_t mailbox, msg_task_t * task, msg_host_t host, double timeout,
84                                              double rate)
85 {
86   msg_error_t ret = MSG_OK;
87   /* We no longer support getting a task from a specific host */
88   if (host)
89     THROW_UNIMPLEMENTED;
90
91   TRACE_msg_task_get_start();
92   double start_time = MSG_get_clock();
93
94   /* Sanity check */
95   xbt_assert(task, "Null pointer for the task storage");
96
97   if (*task)
98     XBT_WARN("Asked to write the received task in a non empty struct -- proceeding.");
99
100   /* Try to receive it by calling SIMIX network layer */
101   try {
102     simcall_comm_recv(MSG_process_self(), mailbox->getImpl(), task, nullptr, nullptr, nullptr, nullptr, timeout, rate);
103     XBT_DEBUG("Got task %s from %p",(*task)->name,mailbox);
104     (*task)->simdata->setNotUsed();
105   }
106   catch (xbt_ex& e) {
107     switch (e.category) {
108     case cancel_error:
109       ret = MSG_HOST_FAILURE;
110       break;
111     case network_error:
112       ret = MSG_TRANSFER_FAILURE;
113       break;
114     case timeout_error:
115       ret = MSG_TIMEOUT;
116       break;
117     case host_error:
118       ret = MSG_HOST_FAILURE;
119       break;
120     default:
121       throw;
122     }
123   }
124
125   if (ret != MSG_HOST_FAILURE && ret != MSG_TRANSFER_FAILURE && ret != MSG_TIMEOUT) {
126     TRACE_msg_task_get_end(start_time, *task);
127   }
128   MSG_RETURN(ret);
129 }