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 #include "simgrid/s4u/Comm.hpp"
7 #include "simgrid/s4u/Mailbox.hpp"
8 #include "src/kernel/activity/MailboxImpl.hpp"
9 #include <simgrid/mailbox.h>
11 XBT_LOG_EXTERNAL_CATEGORY(s4u);
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_channel, s4u, "S4U Communication Mailboxes");
17 const simgrid::xbt::string& Mailbox::get_name() const
19 return pimpl_->get_name();
22 const char* Mailbox::get_cname() const
24 return pimpl_->get_cname();
27 MailboxPtr Mailbox::by_name(const char* name)
29 kernel::activity::MailboxImpl* mbox = kernel::activity::MailboxImpl::byNameOrNull(name);
30 if (mbox == nullptr) {
31 mbox = simix::simcall([name] { return kernel::activity::MailboxImpl::byNameOrCreate(name); });
33 return MailboxPtr(&mbox->piface_, true);
36 MailboxPtr Mailbox::by_name(std::string name)
38 return by_name(name.c_str());
43 return pimpl_->comm_queue.empty();
46 bool Mailbox::listen()
48 return not this->empty() || (pimpl_->permanent_receiver && not pimpl_->done_comm_queue.empty());
51 smx_activity_t Mailbox::front()
53 return pimpl_->comm_queue.empty() ? nullptr : pimpl_->comm_queue.front();
56 void Mailbox::set_receiver(ActorPtr actor)
58 simix::simcall([this, actor]() { this->pimpl_->setReceiver(actor); });
61 /** @brief get the receiver (process associated to the mailbox) */
62 ActorPtr Mailbox::get_receiver()
64 if (pimpl_->permanent_receiver == nullptr)
66 return pimpl_->permanent_receiver->iface();
69 CommPtr Mailbox::put_init()
71 CommPtr res = CommPtr(new s4u::Comm());
72 res->sender_ = SIMIX_process_self();
76 s4u::CommPtr Mailbox::put_init(void* data, uint64_t simulated_size_in_bytes)
78 s4u::CommPtr res = put_init();
79 res->set_remaining(simulated_size_in_bytes);
80 res->src_buff_ = data;
81 res->src_buff_size_ = sizeof(void*);
84 s4u::CommPtr Mailbox::put_async(void* payload, uint64_t simulated_size_in_bytes)
86 xbt_assert(payload != nullptr, "You cannot send nullptr");
88 s4u::CommPtr res = put_init(payload, simulated_size_in_bytes);
92 void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes)
94 xbt_assert(payload != nullptr, "You cannot send nullptr");
96 CommPtr c = put_init();
97 c->set_remaining(simulated_size_in_bytes);
98 c->set_src_data(payload);
101 /** Blocking send with timeout */
102 void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes, double timeout)
104 xbt_assert(payload != nullptr, "You cannot send nullptr");
106 CommPtr c = put_init();
107 c->set_remaining(simulated_size_in_bytes);
108 c->set_src_data(payload);
109 // c->start() is optional.
113 s4u::CommPtr Mailbox::get_init()
115 CommPtr res = CommPtr(new s4u::Comm());
116 res->receiver_ = SIMIX_process_self();
117 res->mailbox_ = this;
120 s4u::CommPtr Mailbox::get_async(void** data)
122 s4u::CommPtr res = get_init();
123 res->set_dst_data(data, sizeof(*data));
131 CommPtr c = get_init();
132 c->set_dst_data(&res, sizeof(res));
136 void* Mailbox::get(double timeout)
139 CommPtr c = get_init();
140 c->set_dst_data(&res, sizeof(res));
145 } // namespace simgrid
147 /* **************************** Public C interface *************************** */
148 /** \brief Set the mailbox to receive in asynchronous mode
150 * All messages sent to this mailbox will be transferred to the receiver without waiting for the receive call.
151 * The receive call will still be necessary to use the received data.
152 * If there is a need to receive some messages asynchronously, and some not, two different mailboxes should be used.
154 * \param alias The name of the mailbox
156 void sg_mailbox_set_receiver(const char* alias)
158 simgrid::s4u::Mailbox::by_name(alias)->set_receiver(simgrid::s4u::Actor::self());
159 XBT_VERB("%s mailbox set to receive eagerly for myself\n", alias);
162 /** \brief Check if there is a communication going on in a mailbox.
164 * \param alias the name of the mailbox to be considered
165 * \return Returns 1 if there is a communication, 0 otherwise
167 int sg_mailbox_listen(const char* alias)
169 return simgrid::s4u::Mailbox::by_name(alias)->listen() ? 1 : 0;