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