Logo AND Algorithmique Numérique Distribuée

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