1 /* Copyright (c) 2006-2017. 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
13 #include <simgrid/s4u/forward.hpp>
14 #include <simgrid/s4u/Actor.hpp>
19 /** @brief Mailboxes: Network rendez-vous points.
24 * @section s4u_mb_what What are mailboxes
26 * Rendez-vous point for network communications, similar to URLs on
27 * which you could post and retrieve data. Actually, the mailboxes are
28 * not involved in the communication once it starts, but only to find
29 * the contact with which you want to communicate.
31 * Here are some mechanisms similar to the mailbox in other
32 * communication systems: The phone number, which allows the caller to
33 * find the receiver. The twitter hashtag, which help senders and
34 * receivers to find each others. In TCP, the pair {host name, host
35 * port} to which you can connect to find your interlocutor. In HTTP,
36 * URLs through which the clients can connect to the servers.
38 * One big difference with most of these systems is that usually, no
39 * actor is the exclusive owner of a mailbox, neither in sending nor
40 * in receiving. Many actors can send into and/or receive from the
41 * same mailbox. This is a big difference to the socket ports for
42 * example, that are definitely exclusive in receiving.
44 * A big difference with twitter hashtags is that SimGrid does not
45 * offer easy support to broadcast a given message to many
46 * receivers. So that would be like a twitter tag where each message
47 * is consumed by the first coming receiver.
49 * The mailboxes are not located on the network, and you can access
50 * them without any latency. The network delay are only related to the
51 * location of the sender and receiver once the match between them is
52 * done on the mailbox. This is just like the phone number that you
53 * can use locally, and the geographical distance only comes into play
54 * once you start the communication by dialling this number.
56 * @section s4u_mb_howto How to use mailboxes?
58 * Any existing mailbox can be retrieve from its name (which are
59 * unique strings, just like with twitter tags). This results in a
60 * versatile mechanism that can be used to build many different
63 * For something close to classical socket communications, use
64 * "hostname:port" as mailbox names, and make sure that only one actor
65 * reads into that mailbox. It's hard to build a prefectly realistic
66 * model of the TCP sockets, but most of the time, this system is too
67 * cumbersome for your simulations anyway. You probably want something
68 * simpler, that turns our to be easy to build with the mailboxes.
70 * Many SimGrid examples use a sort of yellow page system where the
71 * mailbox names are the name of the service (such as "worker",
72 * "master" or "reducer"). That way, you don't have to know where your
73 * peer is located to contact it. You don't even need its name. Its
74 * function is enough for that. This also gives you some sort of load
75 * balancing for free if more than one actor pulls from the mailbox:
76 * the first relevant actor that can deal with the request will handle
79 * @section s4u_mb_matching How are sends and receives matched?
81 * The matching algorithm is as simple as a first come, first
82 * serve. When a new send arrives, it matches the oldest enqueued
83 * receive. If no receive is currently enqueued, then the incomming
84 * send is enqueued. As you can see, the mailbox cannot contain both
85 * send and receive requests: all enqueued requests must be of the
88 * @section s4u_mb_receiver Declaring a receiving actor
90 * The last twist is that by default in the simulator, the data starts
91 * to be exchanged only when both the sender and the receiver are
92 * declared while in real systems (such as TCP or MPI), the data
93 * starts to flow as soon as the sender posts it, even if the receiver
94 * did not post its recv() yet. This can obviously lead to bad
95 * simulation timings, as the simulated communications do not start at
96 * the exact same time than the real ones.
98 * If the simulation timings are very important to you, you can
99 * declare a specific receiver to a given mailbox (with the function
100 * setReceiver()). That way, any send() posted to that mailbox will
101 * start as soon as possible, and the data will already be there on
102 * the receiver host when the receiver actor posts its receive().
104 * @section s4u_mb_api The API
106 XBT_PUBLIC_CLASS Mailbox {
108 friend simgrid::s4u::Engine;
109 friend simgrid::kernel::activity::MailboxImpl;
111 simgrid::kernel::activity::MailboxImpl* pimpl_;
113 explicit Mailbox(kernel::activity::MailboxImpl * mbox) : pimpl_(mbox) {}
115 /** private function to manage the mailboxes' lifetime (see @ref s4u_raii) */
116 friend void intrusive_ptr_add_ref(Mailbox*) {}
117 /** private function to manage the mailboxes' lifetime (see @ref s4u_raii) */
118 friend void intrusive_ptr_release(Mailbox*) {}
120 /** private function, do not use. FIXME: make me protected */
121 kernel::activity::MailboxImpl* getImpl() { return pimpl_; }
123 /** Gets the name of that mailbox */
124 const char* getName();
126 /** Retrieve the mailbox associated to the given C string */
127 static MailboxPtr byName(const char *name);
129 /** Retrieve the mailbox associated to the given C++ string */
130 static MailboxPtr byName(std::string name);
132 /** Returns whether the mailbox contains queued communications */
135 /** Check if there is a communication going on in a mailbox. */
138 /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */
139 smx_activity_t front();
141 /** Declare that the specified actor is a permanent receiver on that mailbox
143 * It means that the communications sent to this mailbox will start flowing to
144 * its host even before he does a recv(). This models the real behavior of TCP
145 * and MPI communications, amongst other.
147 void setReceiver(ActorPtr actor);
149 /** Return the actor declared as permanent receiver, or nullptr if none **/
150 ActorPtr getReceiver();
152 /** Creates (but don't start) a data emission to that mailbox */
154 /** Creates (but don't start) a data emission to that mailbox */
155 CommPtr put_init(void* data, uint64_t simulatedSizeInBytes);
156 /** Creates and start a data emission to that mailbox */
157 CommPtr put_async(void* data, uint64_t simulatedSizeInBytes);
159 /** Blocking data emission */
160 void put(void* payload, uint64_t simulatedSizeInBytes);
161 /** Blocking data emission with timeout */
162 void put(void* payload, uint64_t simulatedSizeInBytes, double timeout);
164 /** Creates (but don't start) a data reception onto that mailbox */
166 /** Creates and start an async data reception to that mailbox */
167 CommPtr get_async(void** data);
169 /** Blocking data reception */
171 /** Blocking data reception with timeout */
172 void* get(double timeout);
175 }} // namespace simgrid::s4u
177 #endif /* SIMGRID_S4U_MAILBOX_HPP */