memory gets properly reclaimed. This call should be at the end of the
actor's function, not in an on_exit callback.
+===============================
+Communicating without Mailboxes
+===============================
+
+Sometimes you don't want to simulate communications between actors as
+allowed by mailboxes, but you want to create a direct communication
+between two arbitrary hosts. This can arise when you write a
+high-level model of a centralized scheduler, or when you model direct
+communications such as one-sided communications in MPI or remote
+memory direct access in PGAS.
+
+For that, :cpp:func:`Comm::sendto() <simgrid::s4u::Comm::sendto()>`
+simulates a direct communication between the two specified hosts. No
+mailbox is used, and there is no rendezvous between actors. You can
+freely mix such direct communications and rendezvous-based
+communications. Alternatively, :cpp:func:`Comm::sendto_init()
+<simgrid::s4u::Comm::sendto_init()>` and
+:cpp:func:`Comm::sendto_async() <simgrid::s4u::Comm::sendto_async()>`
+create asynchronous direct communications.
+
.. _s4u_raii:
Memory Management
Platform and routing
--------------------
+You can also start direct communications between two arbitrary hosts
+using :cpp:func:`Comm::sendto() <simgrid::s4u::Comm::sendto()>`.
+
.. tabs::
.. group-tab:: C++
.. doxygenfunction:: simgrid::s4u::Host::get_netpoint() const
.. doxygenfunction:: simgrid::s4u::Host::route_to(const Host *dest, std::vector< Link * > &links, double *latency) const
.. doxygenfunction:: simgrid::s4u::Host::route_to(const Host *dest, std::vector< kernel::resource::LinkImpl * > &links, double *latency) const
- .. doxygenfunction:: simgrid::s4u::Host::sendto(Host *dest, double byte_amount)
- .. doxygenfunction:: simgrid::s4u::Host::sendto_async(Host *dest, double byte_amount)
.. group-tab:: C
Life cycle
----------
+Most communications are created using :ref:`s4u_mailbox`, but you can
+also start direct communications as shown below.
+
.. tabs::
.. group-tab:: C++
+ .. doxygenfunction:: simgrid::s4u::Comm::sendto
+ .. doxygenfunction:: simgrid::s4u::Comm::sendto_init
+ .. doxygenfunction:: simgrid::s4u::Comm::sendto_async
+
.. doxygenfunction:: simgrid::s4u::Comm::cancel
.. doxygenfunction:: simgrid::s4u::Comm::start
.. doxygenfunction:: simgrid::s4u::Comm::test
/*! Creates a communication beween the two given hosts, bypassing the mailbox mechanism. */
static CommPtr sendto_init(Host* from, Host* to);
- /*! Creates and start a communication of the given amount of bytes beween the two given hosts, bypassing the mailbox
- * mechanism */
+ /** Do an asynchronous communication between two arbitrary hosts.
+ *
+ * This initializes a communication that completely bypass the mailbox and actors mechanism.
+ * There is really no limit on the hosts involved. In particular, the actor does not have to be on one of the involved
+ * hosts.
+ */
static CommPtr sendto_async(Host* from, Host* to, double simulated_size_in_bytes);
+ /** Do a blocking communication between two arbitrary hosts.
+ *
+ * This starts a blocking communication right away, bypassing the mailbox and actors mechanism.
+ * The calling actor is blocked until the end of the communication; there is really no limit on the hosts involved.
+ * In particular, the actor does not have to be on one of the involved hosts. Enjoy the comfort of the simulator :)
+ */
+ static void sendto(Host* from, Host* to, double simulated_size_in_bytes);
static xbt::signal<void(Comm const&, bool is_sender)> on_start;
static xbt::signal<void(Comm const&)> on_completion;
void route_to(const Host* dest, std::vector<Link*>& links, double* latency) const;
void route_to(const Host* dest, std::vector<kernel::resource::LinkImpl*>& links, double* latency) const;
- /** Do a blocking communication between two arbitrary hosts.
- *
- * This starts a blocking communication right away, bypassing the mailbox and actors mechanism.
- * The calling actor is blocked until the end of the communication; there is really no limit on the hosts involved.
- * In particular, the actor does not have to be on one of the involved hosts. Enjoy the comfort of the simulator :)
- */
- void sendto(Host* dest, double byte_amount);
-
- /** Do an asynchronous communication between two arbitrary hosts.
- *
- * This initializes a communication that completely bypass the mailbox and actors mechanism.
- * There is really no limit on the hosts involved. In particular, the actor does not have to be on one of the involved
- * hosts.
- */
- CommPtr sendto_async(Host* dest, double byte_amount);
#ifndef DOXYGEN
- XBT_ATTRIB_DEPRECATED_v330("Please use Host::sendto()") void send_to(Host* dest, double byte_amount)
- {
- sendto(dest, byte_amount);
- }
+ XBT_ATTRIB_DEPRECATED_v331("Please use Comm::sendto()") void sendto(Host* dest, double byte_amount);
+
+ XBT_ATTRIB_DEPRECATED_v331("Please use Comm::sendto_async()") CommPtr sendto_async(Host* dest, double byte_amount);
+
+ XBT_ATTRIB_DEPRECATED_v330("Please use Host::sendto()") void send_to(Host* dest, double byte_amount);
#endif
NetZone* get_englobing_zone();
#include "simgrid/plugins/file_system.h"
#include "simgrid/s4u/Actor.hpp"
+#include "simgrid/s4u/Comm.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "src/surf/HostImpl.hpp"
#include "src/surf/xml/platf_private.hpp"
if (host && host->get_name() != Host::current()->get_name() && read_size > 0) {
/* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */
XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), read_size);
- host->sendto(Host::current(), read_size);
+ Comm::sendto(host, Host::current(), read_size);
}
return read_size;
if (host && host->get_name() != Host::current()->get_name()) {
/* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */
XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), size);
- Host::current()->sendto(host, size);
+ Comm::sendto(Host::current(), host, size);
}
XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu' '%llu:%llu'", get_path(), local_disk_->get_cname(), size, size_,
sg_disk_get_size_used(local_disk_), sg_disk_get_size(local_disk_));
if (src_host) {
XBT_DEBUG("Initiate data transfer of %llu bytes between %s and %s.", read_size, src_host->get_cname(),
dst_host->get_cname());
- src_host->sendto(dst_host, read_size);
+ Comm::sendto(src_host, dst_host, read_size);
}
/* Create file on remote host, write it and close it */
return res;
}
+void Comm::sendto(Host* from, Host* to, double simulated_size_in_bytes)
+{
+ sendto_async(from, to, simulated_size_in_bytes)->wait();
+}
+
Comm* Comm::start()
{
xbt_assert(get_state() == State::INITED || get_state() == State::STARTING,
return pimpl_netpoint_->get_englobing_zone()->get_iface();
}
-void Host::sendto(Host* dest, double byte_amount)
+void Host::sendto(Host* dest, double byte_amount) // deprecated 331
{
- sendto_async(dest, byte_amount)->wait();
+ Comm::sendto_async(this, dest, byte_amount)->wait();
}
-CommPtr Host::sendto_async(Host* dest, double byte_amount)
+CommPtr Host::sendto_async(Host* dest, double byte_amount) // deprecated 331
{
return Comm::sendto_async(this, dest, byte_amount);
}
+void Host::send_to(Host* dest, double byte_amount) // deprecated 330
+{
+ Comm::sendto(this, dest, byte_amount);
+}
+
/** Get the properties assigned to a host */
const std::unordered_map<std::string, std::string>* Host::get_properties() const
{
void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount)
{
- from->sendto(to, byte_amount);
+ simgrid::s4u::Comm::sendto(from, to, byte_amount);
}
/** @brief Displays debugging information about a host */
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5", all_hosts[1], [&global]() {
assert_exit(true, 5.);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
global = true;
});
XBT_INFO("Launch a dcomm(5s), and kill it right after start");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_killed", all_hosts[1], []() {
assert_exit(false, 0);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
FAIL("I should be dead now");
});
XBT_INFO("Launch a dcomm(5s), and kill it after 2 secs");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_killed", all_hosts[1], []() {
assert_exit(false, 2);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
FAIL("I should be dead now");
});
XBT_INFO("Launch a dcomm(5s), and restart its host right after start");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() {
assert_exit(false, 0);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
FAIL("I should be dead now");
});
XBT_INFO("Launch a dcomm(5s), and restart its host after 2 secs");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() {
assert_exit(false, 2);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
FAIL("I should be dead now");
});
simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], [&execution_done]() {
assert_exit(true, 5);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
execution_done = true;
});
XBT_INFO("Launch a dcomm(5s), and restart the used link right after start");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() {
assert_exit(true, 0);
- REQUIRE_NETWORK_FAILURE(all_hosts[1]->sendto(all_hosts[2], 5000));
+ REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000));
});
simgrid::s4u::this_actor::yield();
XBT_INFO("Launch a dcomm(5s), and restart the used link after 2 secs");
simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() {
assert_exit(true, 2);
- REQUIRE_NETWORK_FAILURE(all_hosts[1]->sendto(all_hosts[2], 5000));
+ REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000));
});
simgrid::s4u::this_actor::sleep_for(2);
simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], [&execution_done]() {
assert_exit(true, 5);
- all_hosts[1]->sendto(all_hosts[2], 5000);
+ simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000);
execution_done = true;
});