Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5fecc9563d7500b64e5aeb564d86cecba782a016
[simgrid.git] / src / s4u / s4u_comm.cpp
1 /* Copyright (c) 2006-2017. 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 "xbt/log.h"
7 #include "src/msg/msg_private.h"
8
9 #include "simgrid/s4u/Comm.hpp"
10 #include "simgrid/s4u/Mailbox.hpp"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm,s4u_activity,"S4U asynchronous communications");
13
14 namespace simgrid {
15 namespace s4u {
16
17 Comm::~Comm() {
18
19 }
20
21
22
23 s4u::Comm &Comm::send_init(s4u::MailboxPtr chan) {
24   s4u::Comm *res = new s4u::Comm();
25   res->sender_ = SIMIX_process_self();
26   res->mailbox_ = chan;
27   return *res;
28 }
29
30 s4u::Comm &Comm::recv_init(s4u::MailboxPtr chan) {
31   s4u::Comm *res = new s4u::Comm();
32   res->receiver_ = SIMIX_process_self();
33   res->mailbox_ = chan;
34   return *res;
35 }
36
37 void Comm::setRate(double rate) {
38   xbt_assert(state_==inited);
39   rate_ = rate;
40 }
41
42 void Comm::setSrcData(void * buff) {
43   xbt_assert(state_==inited);
44   xbt_assert(dstBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
45   srcBuff_ = buff;
46 }
47 void Comm::setSrcDataSize(size_t size){
48   xbt_assert(state_==inited);
49   srcBuffSize_ = size;
50 }
51 void Comm::setSrcData(void * buff, size_t size) {
52   xbt_assert(state_==inited);
53
54   xbt_assert(dstBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
55   srcBuff_ = buff;
56   srcBuffSize_ = size;
57 }
58 void Comm::setDstData(void ** buff) {
59   xbt_assert(state_==inited);
60   xbt_assert(srcBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
61   dstBuff_ = buff;
62 }
63 size_t Comm::getDstDataSize(){
64   xbt_assert(state_==finished);
65   return dstBuffSize_;
66 }
67 void Comm::setDstData(void ** buff, size_t size) {
68   xbt_assert(state_==inited);
69
70   xbt_assert(srcBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
71   dstBuff_ = buff;
72   dstBuffSize_ = size;
73 }
74
75 void Comm::start() {
76   xbt_assert(state_ == inited);
77
78   if (srcBuff_ != nullptr) { // Sender side
79     pimpl_ = simcall_comm_isend(sender_, mailbox_->getImpl(), remains_, rate_,
80         srcBuff_, srcBuffSize_,
81         matchFunction_, cleanFunction_, copyDataFunction_,
82         userData_, detached_);
83   } else if (dstBuff_ != nullptr) { // Receiver side
84     pimpl_ = simcall_comm_irecv(receiver_, mailbox_->getImpl(), dstBuff_, &dstBuffSize_,
85         matchFunction_, copyDataFunction_,
86         userData_, rate_);
87
88   } else {
89     xbt_die("Cannot start a communication before specifying whether we are the sender or the receiver");
90   }
91   state_ = started;
92 }
93 void Comm::wait() {
94   xbt_assert(state_ == started || state_ == inited);
95
96   if (state_ == started)
97     simcall_comm_wait(pimpl_, -1/*timeout*/);
98   else {// p_state == inited. Save a simcall and do directly a blocking send/recv
99     if (srcBuff_ != nullptr) {
100       simcall_comm_send(sender_, mailbox_->getImpl(), remains_, rate_,
101           srcBuff_, srcBuffSize_,
102           matchFunction_, copyDataFunction_,
103           userData_, -1 /*timeout*/);
104     } else {
105       simcall_comm_recv(receiver_, mailbox_->getImpl(), dstBuff_, &dstBuffSize_,
106           matchFunction_, copyDataFunction_,
107           userData_, -1/*timeout*/, rate_);
108     }
109   }
110   state_ = finished;
111   delete this;
112 }
113 void Comm::wait(double timeout) {
114   xbt_assert(state_ == started || state_ == inited);
115
116   if (state_ == started) {
117     simcall_comm_wait(pimpl_, timeout);
118     state_ = finished;
119     return;
120   }
121
122   // It's not started yet. Do it in one simcall
123   if (srcBuff_ != nullptr) {
124     simcall_comm_send(sender_, mailbox_->getImpl(), remains_, rate_,
125         srcBuff_, srcBuffSize_,
126         matchFunction_, copyDataFunction_,
127         userData_, timeout);
128   } else { // Receiver
129     simcall_comm_recv(receiver_, mailbox_->getImpl(), dstBuff_, &dstBuffSize_,
130         matchFunction_, copyDataFunction_,
131         userData_, timeout, rate_);
132   }
133   state_ = finished;
134   delete this;
135 }
136
137 s4u::Comm &Comm::send_async(MailboxPtr dest, void *data, int simulatedSize) {
138   s4u::Comm &res = s4u::Comm::send_init(dest);
139   res.setRemains(simulatedSize);
140   res.srcBuff_ = data;
141   res.srcBuffSize_ = sizeof(void*);
142   res.start();
143   return res;
144 }
145
146 s4u::Comm &Comm::recv_async(MailboxPtr dest, void **data) {
147   s4u::Comm &res = s4u::Comm::recv_init(dest);
148   res.setDstData(data, sizeof(*data));
149   res.start();
150   return res;
151 }
152
153 bool Comm::test() {
154   xbt_assert(state_ == inited || state_ == started || state_ == finished);
155   
156   if (state_ == finished) 
157     xbt_die("Don't call test on a finished comm.");
158   
159   if (state_ == inited) {
160     this->start();
161   }
162   
163   if(simcall_comm_test(pimpl_)){
164     state_ = finished;
165     delete this;
166     return true;
167   }
168   return false;
169 }
170
171 }
172 }