Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
d27cfb096831be4e5eb87ce9de1a153d58230d8c
[simgrid.git] / src / s4u / s4u_comm.cpp
1 /* Copyright (c) 2006-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "xbt/log.h"
8 #include "src/msg/msg_private.h"
9
10 #include "simgrid/s4u/comm.hpp"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm,s4u_activity,"S4U asynchronous communications");
13 using namespace simgrid;
14
15 s4u::Comm::~Comm() {
16
17 }
18
19 s4u::Comm &s4u::Comm::send_init(s4u::Mailbox &chan) {
20   s4u::Comm *res = new s4u::Comm();
21   res->sender_ = SIMIX_process_self();
22   res->mailbox_ = &chan;
23   return *res;
24 }
25
26 s4u::Comm &s4u::Comm::recv_init(s4u::Mailbox &chan) {
27   s4u::Comm *res = new s4u::Comm();
28   res->receiver_ = SIMIX_process_self();
29   res->mailbox_ = &chan;
30   return *res;
31 }
32
33 void s4u::Comm::setRate(double rate) {
34   xbt_assert(state_==inited);
35   rate_ = rate;
36 }
37
38 void s4u::Comm::setSrcData(void * buff) {
39   xbt_assert(state_==inited);
40   xbt_assert(dstBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
41   srcBuff_ = buff;
42 }
43 void s4u::Comm::setSrcDataSize(size_t size){
44   xbt_assert(state_==inited);
45   srcBuffSize_ = size;
46 }
47 void s4u::Comm::setSrcData(void * buff, size_t size) {
48   xbt_assert(state_==inited);
49
50   xbt_assert(dstBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
51   srcBuff_ = buff;
52   srcBuffSize_ = size;
53 }
54 void s4u::Comm::setDstData(void ** buff) {
55   xbt_assert(state_==inited);
56   xbt_assert(srcBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
57   dstBuff_ = buff;
58 }
59 size_t s4u::Comm::getDstDataSize(){
60   xbt_assert(state_==finished);
61   return dstBuffSize_;
62 }
63 void s4u::Comm::setDstData(void ** buff, size_t size) {
64   xbt_assert(state_==inited);
65
66   xbt_assert(srcBuff_ == nullptr, "Cannot set the src and dst buffers at the same time");
67   dstBuff_ = buff;
68   dstBuffSize_ = size;
69 }
70
71 void s4u::Comm::start() {
72   xbt_assert(state_ == inited);
73
74   if (srcBuff_ != nullptr) { // Sender side
75     pimpl_ = simcall_comm_isend(sender_, mailbox_->getInferior(), remains_, rate_,
76         srcBuff_, srcBuffSize_,
77         matchFunction_, cleanFunction_, copyDataFunction_,
78         userData_, detached_);
79   } else if (dstBuff_ != nullptr) { // Receiver side
80     pimpl_ = simcall_comm_irecv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
81         matchFunction_, copyDataFunction_,
82         userData_, rate_);
83
84   } else {
85     xbt_die("Cannot start a communication before specifying whether we are the sender or the receiver");
86   }
87   state_ = started;
88 }
89 void s4u::Comm::wait() {
90   xbt_assert(state_ == started || state_ == inited);
91
92   if (state_ == started)
93     simcall_comm_wait(pimpl_, -1/*timeout*/);
94   else {// p_state == inited. Save a simcall and do directly a blocking send/recv
95     if (srcBuff_ != nullptr) {
96       simcall_comm_send(sender_, mailbox_->getInferior(), remains_, rate_,
97           srcBuff_, srcBuffSize_,
98           matchFunction_, copyDataFunction_,
99           userData_, -1 /*timeout*/);
100     } else {
101       simcall_comm_recv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
102           matchFunction_, copyDataFunction_,
103           userData_, -1/*timeout*/, rate_);
104     }
105   }
106   state_ = finished;
107 }
108 void s4u::Comm::wait(double timeout) {
109   xbt_assert(state_ == started || state_ == inited);
110
111   if (state_ == started) {
112     simcall_comm_wait(pimpl_, timeout);
113     state_ = finished;
114     return;
115   }
116
117   // It's not started yet. Do it in one simcall
118   if (srcBuff_ != nullptr) {
119     simcall_comm_send(sender_, mailbox_->getInferior(), remains_, rate_,
120         srcBuff_, srcBuffSize_,
121         matchFunction_, copyDataFunction_,
122         userData_, timeout);
123   } else { // Receiver
124     simcall_comm_recv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
125         matchFunction_, copyDataFunction_,
126         userData_, timeout, rate_);
127   }
128   state_ = finished;
129 }
130
131 s4u::Comm &s4u::Comm::send_async(Mailbox &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 &s4u::Comm::recv_async(Mailbox &dest, void **data) {
141   s4u::Comm &res = s4u::Comm::recv_init(dest);
142   res.setDstData(data);
143   res.start();
144   return res;
145 }
146