This source file includes following definitions.
- mca_btl_tcp2_frag_common_constructor
- mca_btl_tcp2_frag_eager_constructor
- mca_btl_tcp2_frag_max_constructor
- mca_btl_tcp2_frag_user_constructor
- mca_btl_tcp2_frag_send
- mca_btl_tcp2_frag_recv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include "ompi_config.h"
27
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
30 #endif
31 #ifdef HAVE_SYS_UIO_H
32 #include <sys/uio.h>
33 #endif
34 #ifdef HAVE_NET_UIO_H
35 #include <net/uio.h>
36 #endif
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #include "opal/opal_socket_errno.h"
42 #include "ompi/mca/btl/base/btl_base_error.h"
43 #include "btl_tcp2_frag.h"
44 #include "btl_tcp2_endpoint.h"
45
46 static void mca_btl_tcp2_frag_common_constructor(mca_btl_tcp2_frag_t* frag)
47 {
48 frag->base.des_src = NULL;
49 frag->base.des_src_cnt = 0;
50 frag->base.des_dst = NULL;
51 frag->base.des_dst_cnt = 0;
52 }
53
54 static void mca_btl_tcp2_frag_eager_constructor(mca_btl_tcp2_frag_t* frag)
55 {
56 frag->size = mca_btl_tcp2_module.super.btl_eager_limit;
57 frag->my_list = &mca_btl_tcp2_component.tcp_frag_eager;
58 mca_btl_tcp2_frag_common_constructor(frag);
59 }
60
61 static void mca_btl_tcp2_frag_max_constructor(mca_btl_tcp2_frag_t* frag)
62 {
63 frag->size = mca_btl_tcp2_module.super.btl_max_send_size;
64 frag->my_list = &mca_btl_tcp2_component.tcp_frag_max;
65 mca_btl_tcp2_frag_common_constructor(frag);
66 }
67
68 static void mca_btl_tcp2_frag_user_constructor(mca_btl_tcp2_frag_t* frag)
69 {
70 frag->size = 0;
71 frag->my_list = &mca_btl_tcp2_component.tcp_frag_user;
72 mca_btl_tcp2_frag_common_constructor(frag);
73 }
74
75
76 OBJ_CLASS_INSTANCE(
77 mca_btl_tcp2_frag_t,
78 mca_btl_base_descriptor_t,
79 NULL,
80 NULL);
81
82 OBJ_CLASS_INSTANCE(
83 mca_btl_tcp2_frag_eager_t,
84 mca_btl_base_descriptor_t,
85 mca_btl_tcp2_frag_eager_constructor,
86 NULL);
87
88 OBJ_CLASS_INSTANCE(
89 mca_btl_tcp2_frag_max_t,
90 mca_btl_base_descriptor_t,
91 mca_btl_tcp2_frag_max_constructor,
92 NULL);
93
94 OBJ_CLASS_INSTANCE(
95 mca_btl_tcp2_frag_user_t,
96 mca_btl_base_descriptor_t,
97 mca_btl_tcp2_frag_user_constructor,
98 NULL);
99
100
101 bool mca_btl_tcp2_frag_send(mca_btl_tcp2_frag_t* frag, int sd)
102 {
103 int cnt=-1;
104 size_t i, num_vecs;
105
106
107 while(cnt < 0) {
108 cnt = writev(sd, frag->iov_ptr, frag->iov_cnt);
109 if(cnt < 0) {
110 switch(opal_socket_errno) {
111 case EINTR:
112 continue;
113 case EWOULDBLOCK:
114 return false;
115 case EFAULT:
116 BTL_ERROR(("mca_btl_tcp2_frag_send: writev error (%p, %lu)\n\t%s(%lu)\n",
117 frag->iov_ptr[0].iov_base, (unsigned long) frag->iov_ptr[0].iov_len,
118 strerror(opal_socket_errno), (unsigned long) frag->iov_cnt));
119 mca_btl_tcp2_endpoint_close(frag->endpoint);
120 return false;
121 default:
122 BTL_ERROR(("mca_btl_tcp2_frag_send: writev failed: %s (%d)",
123 strerror(opal_socket_errno),
124 opal_socket_errno));
125 mca_btl_tcp2_endpoint_close(frag->endpoint);
126 return false;
127 }
128 }
129 }
130
131
132 num_vecs = frag->iov_cnt;
133 for(i=0; i<num_vecs; i++) {
134 if(cnt >= (int)frag->iov_ptr->iov_len) {
135 cnt -= frag->iov_ptr->iov_len;
136 frag->iov_ptr++;
137 frag->iov_idx++;
138 frag->iov_cnt--;
139 } else {
140 frag->iov_ptr->iov_base = (ompi_iov_base_ptr_t)
141 (((unsigned char*)frag->iov_ptr->iov_base) + cnt);
142 frag->iov_ptr->iov_len -= cnt;
143 break;
144 }
145 }
146 return (frag->iov_cnt == 0);
147 }
148
149 bool mca_btl_tcp2_frag_recv(mca_btl_tcp2_frag_t* frag, int sd)
150 {
151 int cnt, dont_copy_data = 0;
152 size_t i, num_vecs;
153 mca_btl_base_endpoint_t* btl_endpoint = frag->endpoint;
154
155 repeat:
156 num_vecs = frag->iov_cnt;
157 #if MCA_BTL_TCP_ENDPOINT_CACHE
158 if( 0 != btl_endpoint->endpoint_cache_length ) {
159 size_t length;
160
161
162
163
164 cnt = length = btl_endpoint->endpoint_cache_length;
165 for( i = 0; i < frag->iov_cnt; i++ ) {
166 if( length > frag->iov_ptr[i].iov_len )
167 length = frag->iov_ptr[i].iov_len;
168 if( (0 == dont_copy_data) || (length < frag->iov_ptr[i].iov_len) ) {
169 memcpy( frag->iov_ptr[i].iov_base, btl_endpoint->endpoint_cache_pos, length );
170 } else {
171 frag->segments[0].seg_addr.pval = btl_endpoint->endpoint_cache_pos;
172 frag->iov_ptr[i].iov_base = btl_endpoint->endpoint_cache_pos;
173 }
174 btl_endpoint->endpoint_cache_pos += length;
175 btl_endpoint->endpoint_cache_length -= length;
176 length = btl_endpoint->endpoint_cache_length;
177 if( 0 == length ) {
178 btl_endpoint->endpoint_cache_pos = btl_endpoint->endpoint_cache;
179 break;
180 }
181 }
182 goto advance_iov_position;
183 }
184
185
186
187 frag->iov_ptr[num_vecs].iov_base = btl_endpoint->endpoint_cache_pos;
188 frag->iov_ptr[num_vecs].iov_len =
189 mca_btl_tcp2_component.tcp_endpoint_cache - btl_endpoint->endpoint_cache_length;
190 num_vecs++;
191 #endif
192
193
194 cnt = -1;
195 while( cnt < 0 ) {
196 cnt = readv(sd, frag->iov_ptr, num_vecs);
197 if( 0 < cnt ) goto advance_iov_position;
198 if( cnt == 0 ) {
199 mca_btl_tcp2_endpoint_close(btl_endpoint);
200 return false;
201 }
202 switch(opal_socket_errno) {
203 case EINTR:
204 continue;
205 case EWOULDBLOCK:
206 return false;
207 case EFAULT:
208 BTL_ERROR(("mca_btl_tcp2_frag_recv: readv error (%p, %lu)\n\t%s(%lu)\n",
209 frag->iov_ptr[0].iov_base, (unsigned long) frag->iov_ptr[0].iov_len,
210 strerror(opal_socket_errno), (unsigned long) frag->iov_cnt));
211 mca_btl_tcp2_endpoint_close(btl_endpoint);
212 return false;
213 default:
214 BTL_ERROR(("mca_btl_tcp2_frag_recv: readv failed: %s (%d)",
215 strerror(opal_socket_errno),
216 opal_socket_errno));
217 mca_btl_tcp2_endpoint_close(btl_endpoint);
218 return false;
219 }
220 };
221
222 advance_iov_position:
223
224 num_vecs = frag->iov_cnt;
225 for( i = 0; i < num_vecs; i++ ) {
226 if( cnt < (int)frag->iov_ptr->iov_len ) {
227 frag->iov_ptr->iov_base = (ompi_iov_base_ptr_t)
228 (((unsigned char*)frag->iov_ptr->iov_base) + cnt);
229 frag->iov_ptr->iov_len -= cnt;
230 cnt = 0;
231 break;
232 }
233 cnt -= frag->iov_ptr->iov_len;
234 frag->iov_idx++;
235 frag->iov_ptr++;
236 frag->iov_cnt--;
237 }
238 #if MCA_BTL_TCP_ENDPOINT_CACHE
239 btl_endpoint->endpoint_cache_length = cnt;
240 #endif
241
242
243 if(frag->iov_cnt == 0) {
244 if (btl_endpoint->endpoint_nbo && frag->iov_idx == 1) MCA_BTL_TCP_HDR_NTOH(frag->hdr);
245 switch(frag->hdr.type) {
246 case MCA_BTL_TCP_HDR_TYPE_SEND:
247 if(frag->iov_idx == 1 && frag->hdr.size) {
248 frag->segments[0].seg_addr.pval = frag+1;
249 frag->segments[0].seg_len = frag->hdr.size;
250 frag->iov[1].iov_base = (IOVBASE_TYPE*)(frag->segments[0].seg_addr.pval);
251 frag->iov[1].iov_len = frag->hdr.size;
252 frag->iov_cnt++;
253 #ifndef __sparc
254
255
256
257
258 dont_copy_data = 1;
259 #endif
260 goto repeat;
261 }
262 break;
263 case MCA_BTL_TCP_HDR_TYPE_PUT:
264 if(frag->iov_idx == 1) {
265 frag->iov[1].iov_base = (IOVBASE_TYPE*)frag->segments;
266 frag->iov[1].iov_len = frag->hdr.count * sizeof(mca_btl_base_segment_t);
267 frag->iov_cnt++;
268 goto repeat;
269 } else if (frag->iov_idx == 2) {
270 for( i = 0; i < frag->hdr.count; i++ ) {
271 frag->iov[i+2].iov_base = (IOVBASE_TYPE*)ompi_ptr_ltop(frag->segments[i].seg_addr.lval);
272 frag->iov[i+2].iov_len = frag->segments[i].seg_len;
273 }
274 frag->iov_cnt += frag->hdr.count;
275 goto repeat;
276 }
277 break;
278 case MCA_BTL_TCP_HDR_TYPE_GET:
279 default:
280 break;
281 }
282 return true;
283 }
284 return false;
285 }
286