1
1

A first cut at the large data problem with TCP. As long

as the writev and readv support a sum larger than a uint32_t
this version will work. For the other OSes a different patch
is required. This patch is a slight modification of the one
proposed by @ggouaillardet.

Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
Этот коммит содержится в:
George Bosilca 2015-12-03 10:47:00 -05:00
родитель 4db3730a25
Коммит c340da2586
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 09C926752C9F09B1
2 изменённых файлов: 10 добавлений и 11 удалений

Просмотреть файл

@ -112,11 +112,11 @@ size_t mca_btl_tcp_frag_dump(mca_btl_tcp_frag_t* frag, char* msg, char* buf, siz
bool mca_btl_tcp_frag_send(mca_btl_tcp_frag_t* frag, int sd) bool mca_btl_tcp_frag_send(mca_btl_tcp_frag_t* frag, int sd)
{ {
ssize_t cnt = -1; ssize_t cnt;
size_t i, num_vecs; size_t i, num_vecs;
/* non-blocking write, but continue if interrupted */ /* non-blocking write, but continue if interrupted */
while(cnt < 0) { do {
cnt = writev(sd, frag->iov_ptr, frag->iov_cnt); cnt = writev(sd, frag->iov_ptr, frag->iov_cnt);
if(cnt < 0) { if(cnt < 0) {
switch(opal_socket_errno) { switch(opal_socket_errno) {
@ -140,7 +140,7 @@ bool mca_btl_tcp_frag_send(mca_btl_tcp_frag_t* frag, int sd)
return false; return false;
} }
} }
} } while(cnt < 0);
/* if the write didn't complete - update the iovec state */ /* if the write didn't complete - update the iovec state */
num_vecs = frag->iov_cnt; num_vecs = frag->iov_cnt;
@ -166,14 +166,14 @@ bool mca_btl_tcp_frag_send(mca_btl_tcp_frag_t* frag, int sd)
bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd) bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd)
{ {
mca_btl_base_endpoint_t* btl_endpoint = frag->endpoint; mca_btl_base_endpoint_t* btl_endpoint = frag->endpoint;
int i, num_vecs, dont_copy_data = 0;
ssize_t cnt; ssize_t cnt;
int32_t i, num_vecs, dont_copy_data = 0;
repeat: repeat:
num_vecs = frag->iov_cnt; num_vecs = frag->iov_cnt;
#if MCA_BTL_TCP_ENDPOINT_CACHE #if MCA_BTL_TCP_ENDPOINT_CACHE
if( 0 != btl_endpoint->endpoint_cache_length ) { if( 0 != btl_endpoint->endpoint_cache_length ) {
size_t length; ssize_t length;
/* It's strange at the first look but cnt have to be set to the full amount of data /* It's strange at the first look but cnt have to be set to the full amount of data
* available. After going to advance_iov_position we will use cnt to detect if there * available. After going to advance_iov_position we will use cnt to detect if there
* is still some data pending. * is still some data pending.
@ -208,8 +208,7 @@ bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd)
#endif /* MCA_BTL_TCP_ENDPOINT_CACHE */ #endif /* MCA_BTL_TCP_ENDPOINT_CACHE */
/* non-blocking read, but continue if interrupted */ /* non-blocking read, but continue if interrupted */
cnt = -1; do {
while( cnt < 0 ) {
cnt = readv(sd, frag->iov_ptr, num_vecs); cnt = readv(sd, frag->iov_ptr, num_vecs);
if( 0 < cnt ) goto advance_iov_position; if( 0 < cnt ) goto advance_iov_position;
if( cnt == 0 ) { if( cnt == 0 ) {
@ -247,7 +246,7 @@ bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd)
mca_btl_tcp_endpoint_close(btl_endpoint); mca_btl_tcp_endpoint_close(btl_endpoint);
return false; return false;
} }
} } while( cnt < 0 );
advance_iov_position: advance_iov_position:
/* if the read didn't complete - update the iovec state */ /* if the read didn't complete - update the iovec state */

Просмотреть файл

@ -53,8 +53,8 @@ struct mca_btl_tcp_frag_t {
mca_btl_tcp_hdr_t hdr; mca_btl_tcp_hdr_t hdr;
struct iovec iov[MCA_BTL_TCP_FRAG_IOVEC_NUMBER + 1]; struct iovec iov[MCA_BTL_TCP_FRAG_IOVEC_NUMBER + 1];
struct iovec *iov_ptr; struct iovec *iov_ptr;
size_t iov_cnt; uint32_t iov_cnt;
size_t iov_idx; uint32_t iov_idx;
size_t size; size_t size;
uint16_t next_step; uint16_t next_step;
int rc; int rc;