1 /* Copyright (c) 2006-2018. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #ifndef SIMGRID_S4U_MAILBOX_HPP
7 #define SIMGRID_S4U_MAILBOX_HPP
9 #include <xbt/string.hpp>
10 #include <simgrid/s4u/Actor.hpp>
17 /** @brief Mailboxes: Network rendez-vous points.
22 * @section s4u_mb_what What are mailboxes
24 * Rendez-vous point for network communications, similar to URLs on
25 * which you could post and retrieve data. Actually, the mailboxes are
26 * not involved in the communication once it starts, but only to find
27 * the contact with which you want to communicate.
29 * Here are some mechanisms similar to the mailbox in other
30 * communication systems: The phone number, which allows the caller to
31 * find the receiver. The twitter hashtag, which help senders and
32 * receivers to find each others. In TCP, the pair {host name, host
33 * port} to which you can connect to find your interlocutor. In HTTP,
34 * URLs through which the clients can connect to the servers.
36 * One big difference with most of these systems is that usually, no
37 * actor is the exclusive owner of a mailbox, neither in sending nor
38 * in receiving. Many actors can send into and/or receive from the
39 * same mailbox. This is a big difference to the socket ports for
40 * example, that are definitely exclusive in receiving.
42 * A big difference with twitter hashtags is that SimGrid does not
43 * offer easy support to broadcast a given message to many
44 * receivers. So that would be like a twitter tag where each message
45 * is consumed by the first coming receiver.
47 * The mailboxes are not located on the network, and you can access
48 * them without any latency. The network delay are only related to the
49 * location of the sender and receiver once the match between them is
50 * done on the mailbox. This is just like the phone number that you
51 * can use locally, and the geographical distance only comes into play
52 * once you start the communication by dialling this number.
54 * @section s4u_mb_howto How to use mailboxes?
56 * Any existing mailbox can be retrieve from its name (which are
57 * unique strings, just like with twitter tags). This results in a
58 * versatile mechanism that can be used to build many different
61 * For something close to classical socket communications, use
62 * "hostname:port" as mailbox names, and make sure that only one actor
63 * reads into that mailbox. It's hard to build a prefectly realistic
64 * model of the TCP sockets, but most of the time, this system is too
65 * cumbersome for your simulations anyway. You probably want something
66 * simpler, that turns our to be easy to build with the mailboxes.
68 * Many SimGrid examples use a sort of yellow page system where the
69 * mailbox names are the name of the service (such as "worker",
70 * "master" or "reducer"). That way, you don't have to know where your
71 * peer is located to contact it. You don't even need its name. Its
72 * function is enough for that. This also gives you some sort of load
73 * balancing for free if more than one actor pulls from the mailbox:
74 * the first relevant actor that can deal with the request will handle
77 * @section s4u_mb_matching How are sends and receives matched?
79 * The matching algorithm is as simple as a first come, first
80 * serve. When a new send arrives, it matches the oldest enqueued
81 * receive. If no receive is currently enqueued, then the incomming
82 * send is enqueued. As you can see, the mailbox cannot contain both
83 * send and receive requests: all enqueued requests must be of the
86 * @section s4u_mb_receiver Declaring a receiving actor
88 * The last twist is that by default in the simulator, the data starts
89 * to be exchanged only when both the sender and the receiver are
90 * declared while in real systems (such as TCP or MPI), the data
91 * starts to flow as soon as the sender posts it, even if the receiver
92 * did not post its recv() yet. This can obviously lead to bad
93 * simulation timings, as the simulated communications do not start at
94 * the exact same time than the real ones.
96 * If the simulation timings are very important to you, you can
97 * declare a specific receiver to a given mailbox (with the function
98 * setReceiver()). That way, any send() posted to that mailbox will
99 * start as soon as possible, and the data will already be there on
100 * the receiver host when the receiver actor posts its receive().
102 * @section s4u_mb_api The API
104 class XBT_PUBLIC Mailbox {
106 friend simgrid::kernel::activity::MailboxImpl;
108 simgrid::kernel::activity::MailboxImpl* pimpl_;
110 explicit Mailbox(kernel::activity::MailboxImpl * mbox) : pimpl_(mbox) {}
112 /** private function to manage the mailboxes' lifetime (see @ref s4u_raii) */
113 friend void intrusive_ptr_add_ref(Mailbox*) {}
114 /** private function to manage the mailboxes' lifetime (see @ref s4u_raii) */
115 friend void intrusive_ptr_release(Mailbox*) {}
117 /** private function, do not use. FIXME: make me protected */
118 kernel::activity::MailboxImpl* get_impl() { return pimpl_; }
120 /** @brief Retrieves the name of that mailbox as a C++ string */
121 const simgrid::xbt::string& get_name() const;
122 /** @brief Retrieves the name of that mailbox as a C string */
123 const char* get_cname() const;
125 /** Retrieve the mailbox associated to the given C string */
126 static MailboxPtr by_name(const char* name);
128 /** Retrieve the mailbox associated to the given C++ string */
129 static MailboxPtr by_name(std::string name);
131 /** Returns whether the mailbox contains queued communications */
134 /** Check if there is a communication going on in a mailbox. */
137 /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */
138 smx_activity_t front();
140 /** Declare that the specified actor is a permanent receiver on that mailbox
142 * It means that the communications sent to this mailbox will start flowing to
143 * its host even before he does a recv(). This models the real behavior of TCP
144 * and MPI communications, amongst other.
146 void set_receiver(ActorPtr actor);
148 /** Return the actor declared as permanent receiver, or nullptr if none **/
149 ActorPtr get_receiver();
151 /** Creates (but don't start) a data emission to that mailbox */
153 /** Creates (but don't start) a data emission to that mailbox */
154 CommPtr put_init(void* data, uint64_t simulated_size_in_bytes);
155 /** Creates and start a data emission to that mailbox */
156 CommPtr put_async(void* data, uint64_t simulated_size_in_bytes);
158 /** Blocking data emission */
159 void put(void* payload, uint64_t simulated_size_in_bytes);
160 /** Blocking data emission with timeout */
161 void put(void* payload, uint64_t simulated_size_in_bytes, double timeout);
163 /** Creates (but don't start) a data reception onto that mailbox */
165 /** Creates and start an async data reception to that mailbox */
166 CommPtr get_async(void** data);
168 /** Blocking data reception */
169 void* get(); // FIXME: make a typed template version
170 /** Blocking data reception with timeout */
171 void* get(double timeout);
173 // Deprecated functions
174 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::set_receiver()") void setReceiver(ActorPtr actor)
178 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::get_receiver()") ActorPtr getReceiver() { return get_receiver(); }
179 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::get_name()") const simgrid::xbt::string& getName() const
183 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::get_cname()") const char* getCname() const { return get_cname(); }
184 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::get_impl()") kernel::activity::MailboxImpl* getImpl()
188 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::by_name()") static MailboxPtr byName(const char* name)
190 return by_name(name);
192 XBT_ATTRIB_DEPRECATED_v323("Please use Mailbox::by_name()") static MailboxPtr byName(std::string name)
194 return by_name(name);
198 }} // namespace simgrid::s4u
200 #endif /* SIMGRID_S4U_MAILBOX_HPP */