Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
allow to cancel a s4u::Exec
[simgrid.git] / src / s4u / s4u_Mailbox.cpp
1 /* Copyright (c) 2006-2018. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 #include "simgrid/s4u/Comm.hpp"
7 #include "simgrid/s4u/Mailbox.hpp"
8 #include "src/kernel/activity/MailboxImpl.hpp"
9 #include <simgrid/mailbox.h>
10
11 XBT_LOG_EXTERNAL_CATEGORY(s4u);
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_channel, s4u, "S4U Communication Mailboxes");
13
14 namespace simgrid {
15 namespace s4u {
16
17 const simgrid::xbt::string& Mailbox::get_name() const
18 {
19   return pimpl_->get_name();
20 }
21
22 const char* Mailbox::get_cname() const
23 {
24   return pimpl_->get_cname();
25 }
26
27 MailboxPtr Mailbox::by_name(std::string name)
28 {
29   kernel::activity::MailboxImpl* mbox = kernel::activity::MailboxImpl::by_name_or_null(name);
30   if (mbox == nullptr) {
31     mbox = simix::simcall([name] { return kernel::activity::MailboxImpl::by_name_or_create(name); });
32   }
33   return MailboxPtr(&mbox->piface_, true);
34 }
35
36 bool Mailbox::empty()
37 {
38   return pimpl_->comm_queue_.empty();
39 }
40
41 bool Mailbox::listen()
42 {
43   return not this->empty() || (pimpl_->permanent_receiver_ && not pimpl_->done_comm_queue_.empty());
44 }
45
46 smx_activity_t Mailbox::front()
47 {
48   return pimpl_->comm_queue_.empty() ? nullptr : pimpl_->comm_queue_.front();
49 }
50
51 void Mailbox::set_receiver(ActorPtr actor)
52 {
53   simix::simcall([this, actor]() { this->pimpl_->set_receiver(actor); });
54 }
55
56 /** @brief get the receiver (process associated to the mailbox) */
57 ActorPtr Mailbox::get_receiver()
58 {
59   if (pimpl_->permanent_receiver_ == nullptr)
60     return ActorPtr();
61   return pimpl_->permanent_receiver_->iface();
62 }
63
64 CommPtr Mailbox::put_init()
65 {
66   CommPtr res   = CommPtr(new s4u::Comm());
67   res->sender_  = SIMIX_process_self();
68   res->mailbox_ = this;
69   return res;
70 }
71 s4u::CommPtr Mailbox::put_init(void* data, uint64_t simulated_size_in_bytes)
72 {
73   s4u::CommPtr res = put_init();
74   res->set_remaining(simulated_size_in_bytes);
75   res->src_buff_      = data;
76   res->src_buff_size_ = sizeof(void*);
77   return res;
78 }
79 s4u::CommPtr Mailbox::put_async(void* payload, uint64_t simulated_size_in_bytes)
80 {
81   xbt_assert(payload != nullptr, "You cannot send nullptr");
82
83   s4u::CommPtr res = put_init(payload, simulated_size_in_bytes);
84   res->start();
85   return res;
86 }
87 void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes)
88 {
89   xbt_assert(payload != nullptr, "You cannot send nullptr");
90
91   CommPtr c = put_init();
92   c->set_remaining(simulated_size_in_bytes);
93   c->set_src_data(payload);
94   c->wait();
95 }
96 /** Blocking send with timeout */
97 void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes, double timeout)
98 {
99   xbt_assert(payload != nullptr, "You cannot send nullptr");
100
101   CommPtr c = put_init();
102   c->set_remaining(simulated_size_in_bytes);
103   c->set_src_data(payload);
104   // c->start() is optional.
105   c->wait(timeout);
106 }
107
108 s4u::CommPtr Mailbox::get_init()
109 {
110   CommPtr res    = CommPtr(new s4u::Comm());
111   res->receiver_ = SIMIX_process_self();
112   res->mailbox_  = this;
113   return res;
114 }
115 s4u::CommPtr Mailbox::get_async(void** data)
116 {
117   s4u::CommPtr res = get_init();
118   res->set_dst_data(data, sizeof(*data));
119   res->start();
120   return res;
121 }
122
123 void* Mailbox::get()
124 {
125   void* res = nullptr;
126   CommPtr c = get_init();
127   c->set_dst_data(&res, sizeof(res));
128   c->wait();
129   return res;
130 }
131 void* Mailbox::get(double timeout)
132 {
133   void* res = nullptr;
134   CommPtr c = get_init();
135   c->set_dst_data(&res, sizeof(res));
136   c->wait(timeout);
137   return res;
138 }
139 } // namespace s4u
140 } // namespace simgrid
141
142 /* **************************** Public C interface *************************** */
143 /** @brief Set the mailbox to receive in asynchronous mode
144  *
145  * All messages sent to this mailbox will be transferred to the receiver without waiting for the receive call.
146  * The receive call will still be necessary to use the received data.
147  * If there is a need to receive some messages asynchronously, and some not, two different mailboxes should be used.
148  *
149  * @param alias The name of the mailbox
150  */
151 void sg_mailbox_set_receiver(const char* alias)
152 {
153   simgrid::s4u::Mailbox::by_name(alias)->set_receiver(simgrid::s4u::Actor::self());
154   XBT_VERB("%s mailbox set to receive eagerly for myself\n", alias);
155 }
156
157 /** @brief Check if there is a communication going on in a mailbox.
158  *
159  * @param alias the name of the mailbox to be considered
160  * @return Returns 1 if there is a communication, 0 otherwise
161  */
162 int sg_mailbox_listen(const char* alias)
163 {
164   return simgrid::s4u::Mailbox::by_name(alias)->listen() ? 1 : 0;
165 }