SimGrid  3.21
Versatile Simulation of Distributed Systems
simgrid::s4u::Mailbox Class Reference

Detailed Description

Mailboxes: Network rendez-vous points.

What are mailboxes?

Rendez-vous point for network communications, similar to URLs on which you could post and retrieve data. Actually, the mailboxes are not involved in the communication once it starts, but only to find the contact with which you want to communicate.

Here are some mechanisms similar to the mailbox in other communication systems: The phone number, which allows the caller to find the receiver. The twitter hashtag, which help senders and receivers to find each others. In TCP, the pair {host name, host port} to which you can connect to find your interlocutor. In HTTP, URLs through which the clients can connect to the servers. In ZeroMQ and other queuing systems, the queues are used to match senders and receivers.

One big difference with most of these systems is that no actor is the exclusive owner of a mailbox, neither in sending nor in receiving. Many actors can send into and/or receive from the same mailbox. This is a big difference to the socket ports for example, that are definitely exclusive in receiving.

Mailboxes can optionally have a receiver with simgrid::s4u::Mailbox::set_receiver(). It means that the data exchange starts as soon as the sender has done the put(), even before the corresponding get() (usually, it starts as soon as both put() and get() are posted). This is closer to the BSD semantic and can thus help to improve the timing accuracy, but this is not mandatory at all.

A big difference with twitter hashtags is that SimGrid does not offer easy support to broadcast a given message to many receivers. So that would be like a twitter tag where each message is consumed by the first coming receiver.

A big difference with the ZeroMQ queues is that you cannot filter on the data you want to get from the mailbox. To model such settings in SimGrid, you'd have one mailbox per potential topic, and subscribe to each topic individually with a get_async() on each mailbox. Then, use Comm::wait_any() to get the first message on any of the mailbox you are subscribed onto.

The mailboxes are not located on the network, and you can access them without any latency. The network delay are only related to the location of the sender and receiver once the match between them is done on the mailbox. This is just like the phone number that you can use locally, and the geographical distance only comes into play once you start the communication by dialing this number.

How to use mailboxes?

Any existing mailbox can be retrieve from its name (which are unique strings, just like with twitter tags). This results in a versatile mechanism that can be used to build many different situations.

For something close to classical socket communications, use "hostname:port" as mailbox names, and make sure that only one actor reads into that mailbox. It's hard to build a perfectly realistic model of the TCP sockets, but most of the time, this system is too cumbersome for your simulations anyway. You probably want something simpler, that turns our to be easy to build with the mailboxes.

Many SimGrid examples use a sort of yellow page system where the mailbox names are the name of the service (such as "worker", "master" or "reducer"). That way, you don't have to know where your peer is located to contact it. You don't even need its name. Its function is enough for that. This also gives you some sort of load balancing for free if more than one actor pulls from the mailbox: the first relevant actor that can deal with the request will handle it.

How are sends and receives matched?

The matching algorithm is as simple as a first come, first serve. When a new send arrives, it matches the oldest enqueued receive. If no receive is currently enqueued, then the incoming send is enqueued. As you can see, the mailbox cannot contain both send and receive requests: all enqueued requests must be of the same sort.

Declaring a receiving actor

The last twist is that by default in the simulator, the data starts to be exchanged only when both the sender and the receiver are declared while in real systems (such as TCP or MPI), the data starts to flow as soon as the sender posts it, even if the receiver did not post its recv() yet. This can obviously lead to bad simulation timings, as the simulated communications do not start at the exact same time than the real ones.

If the simulation timings are very important to you, you can declare a specific receiver to a given mailbox (with the function setReceiver()). That way, any send() posted to that mailbox will start as soon as possible, and the data will already be there on the receiver host when the receiver actor posts its receive().

The API

#include <Mailbox.hpp>

Public Member Functions

kernel::activity::MailboxImpl * get_impl ()
 private function, do not use. More...
 
const simgrid::xbt::stringget_name () const
 Retrieves the name of that mailbox as a C++ string. More...
 
const char * get_cname () const
 Retrieves the name of that mailbox as a C string. More...
 
bool empty ()
 Returns whether the mailbox contains queued communications. More...
 
bool listen ()
 Check if there is a communication going on in a mailbox. More...
 
bool ready ()
 Check if there is a communication ready to be consumed from a mailbox. More...
 
smx_activity_t front ()
 Gets the first element in the queue (without dequeuing it), or nullptr if none is there. More...
 
void set_receiver (ActorPtr actor)
 Declare that the specified actor is a permanent receiver on that mailbox. More...
 
ActorPtr get_receiver ()
 Return the actor declared as permanent receiver, or nullptr if none. More...
 
CommPtr put_init ()
 Creates (but don't start) a data emission to that mailbox. More...
 
CommPtr put_init (void *data, uint64_t simulated_size_in_bytes)
 Creates (but don't start) a data emission to that mailbox. More...
 
CommPtr put_async (void *data, uint64_t simulated_size_in_bytes)
 Creates and start a data emission to that mailbox. More...
 
void put (void *payload, uint64_t simulated_size_in_bytes)
 Blocking data emission. More...
 
void put (void *payload, uint64_t simulated_size_in_bytes, double timeout)
 Blocking data emission with timeout. More...
 
CommPtr get_init ()
 Creates (but don't start) a data reception onto that mailbox. More...
 
CommPtr get_async (void **data)
 Creates and start an async data reception to that mailbox. More...
 
void * get ()
 Blocking data reception. More...
 
void * get (double timeout)
 Blocking data reception with timeout. More...
 
void setReceiver (ActorPtr actor)
 
ActorPtr getReceiver ()
 
const simgrid::xbt::stringgetName () const
 
const char * getCname () const
 
kernel::activity::MailboxImpl * getImpl ()
 

Static Public Member Functions

static MailboxPtr by_name (std::string name)
 Retrieve the mailbox associated to the given name. More...
 
static MailboxPtr byName (const char *name)
 
static MailboxPtr byName (std::string name)
 

Friends

void intrusive_ptr_add_ref (Mailbox *)
 private function to manage the mailboxes' lifetime (see s4u_raii) More...
 
void intrusive_ptr_release (Mailbox *)
 private function to manage the mailboxes' lifetime (see s4u_raii) More...
 

Member Function Documentation

◆ get_impl()

kernel::activity::MailboxImpl* simgrid::s4u::Mailbox::get_impl ( )
inline

private function, do not use.

FIXME: make me protected

◆ get_name()

const simgrid::xbt::string& simgrid::s4u::Mailbox::get_name ( ) const

Retrieves the name of that mailbox as a C++ string.

◆ get_cname()

const char* simgrid::s4u::Mailbox::get_cname ( ) const

Retrieves the name of that mailbox as a C string.

◆ by_name()

static MailboxPtr simgrid::s4u::Mailbox::by_name ( std::string  name)
static

Retrieve the mailbox associated to the given name.

◆ empty()

bool simgrid::s4u::Mailbox::empty ( )

Returns whether the mailbox contains queued communications.

◆ listen()

bool simgrid::s4u::Mailbox::listen ( )

Check if there is a communication going on in a mailbox.

◆ ready()

bool simgrid::s4u::Mailbox::ready ( )

Check if there is a communication ready to be consumed from a mailbox.

◆ front()

smx_activity_t simgrid::s4u::Mailbox::front ( )

Gets the first element in the queue (without dequeuing it), or nullptr if none is there.

◆ set_receiver()

void simgrid::s4u::Mailbox::set_receiver ( ActorPtr  actor)

Declare that the specified actor is a permanent receiver on that mailbox.

It means that the communications sent to this mailbox will start flowing to its host even before he does a recv(). This models the real behavior of TCP and MPI communications, amongst other. It will improve the accuracy of predictions, in particular if your application exhibits swarms of small messages.

SimGrid does not enforces any kind of ownership over the mailbox. Even if a receiver was declared, any other actors can still get() data from the mailbox. The timings will then probably be off tracks, so you should strive on your side to not get data from someone else's mailbox.

◆ get_receiver()

ActorPtr simgrid::s4u::Mailbox::get_receiver ( )

Return the actor declared as permanent receiver, or nullptr if none.

◆ put_init() [1/2]

CommPtr simgrid::s4u::Mailbox::put_init ( )

Creates (but don't start) a data emission to that mailbox.

◆ put_init() [2/2]

CommPtr simgrid::s4u::Mailbox::put_init ( void *  data,
uint64_t  simulated_size_in_bytes 
)

Creates (but don't start) a data emission to that mailbox.

◆ put_async()

CommPtr simgrid::s4u::Mailbox::put_async ( void *  data,
uint64_t  simulated_size_in_bytes 
)

Creates and start a data emission to that mailbox.

◆ put() [1/2]

void simgrid::s4u::Mailbox::put ( void *  payload,
uint64_t  simulated_size_in_bytes 
)

Blocking data emission.

◆ put() [2/2]

void simgrid::s4u::Mailbox::put ( void *  payload,
uint64_t  simulated_size_in_bytes,
double  timeout 
)

Blocking data emission with timeout.

◆ get_init()

CommPtr simgrid::s4u::Mailbox::get_init ( )

Creates (but don't start) a data reception onto that mailbox.

◆ get_async()

CommPtr simgrid::s4u::Mailbox::get_async ( void **  data)

Creates and start an async data reception to that mailbox.

◆ get() [1/2]

void* simgrid::s4u::Mailbox::get ( )

Blocking data reception.

◆ get() [2/2]

void* simgrid::s4u::Mailbox::get ( double  timeout)

Blocking data reception with timeout.

◆ setReceiver()

void simgrid::s4u::Mailbox::setReceiver ( ActorPtr  actor)
inline

◆ getReceiver()

ActorPtr simgrid::s4u::Mailbox::getReceiver ( )
inline

◆ getName()

const simgrid::xbt::string& simgrid::s4u::Mailbox::getName ( ) const
inline

◆ getCname()

const char* simgrid::s4u::Mailbox::getCname ( ) const
inline

◆ getImpl()

kernel::activity::MailboxImpl* simgrid::s4u::Mailbox::getImpl ( )
inline

◆ byName() [1/2]

static MailboxPtr simgrid::s4u::Mailbox::byName ( const char *  name)
inlinestatic

◆ byName() [2/2]

static MailboxPtr simgrid::s4u::Mailbox::byName ( std::string  name)
inlinestatic

Friends And Related Function Documentation

◆ intrusive_ptr_add_ref

void intrusive_ptr_add_ref ( Mailbox )
friend

private function to manage the mailboxes' lifetime (see s4u_raii)

◆ intrusive_ptr_release

void intrusive_ptr_release ( Mailbox )
friend

private function to manage the mailboxes' lifetime (see s4u_raii)


The documentation for this class was generated from the following file: