2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* All rights reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-01-15 02:24:15 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-10-20 05:03:09 +04:00
|
|
|
#include "ompi_config.h"
|
2004-03-26 17:15:20 +03:00
|
|
|
#include <string.h>
|
2004-11-05 10:52:30 +03:00
|
|
|
#include "class/ompi_bitmap.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "util/output.h"
|
|
|
|
#include "util/if.h"
|
|
|
|
#include "mca/pml/pml.h"
|
|
|
|
#include "mca/ptl/ptl.h"
|
|
|
|
#include "mca/ptl/base/ptl_base_header.h"
|
2005-05-09 23:37:10 +04:00
|
|
|
#include "mca/ptl/base/ptl_base_sendreq.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "mca/ptl/base/ptl_base_sendfrag.h"
|
2005-05-09 23:37:10 +04:00
|
|
|
#include "mca/ptl/base/ptl_base_recvreq.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "mca/ptl/base/ptl_base_recvfrag.h"
|
2004-01-14 18:15:17 +03:00
|
|
|
#include "ptl_tcp.h"
|
2004-01-29 01:52:51 +03:00
|
|
|
#include "ptl_tcp_addr.h"
|
|
|
|
#include "ptl_tcp_peer.h"
|
|
|
|
#include "ptl_tcp_proc.h"
|
2004-02-04 00:33:29 +03:00
|
|
|
#include "ptl_tcp_sendreq.h"
|
2004-03-12 01:02:01 +03:00
|
|
|
#include "ptl_tcp_recvfrag.h"
|
2004-01-14 18:15:17 +03:00
|
|
|
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_module_t mca_ptl_tcp_module = {
|
2004-01-14 18:15:17 +03:00
|
|
|
{
|
2004-08-02 04:24:22 +04:00
|
|
|
&mca_ptl_tcp_component.super,
|
2004-09-10 01:51:01 +04:00
|
|
|
16, /* max size of request cache */
|
2005-05-09 23:37:10 +04:00
|
|
|
sizeof(mca_ptl_tcp_send_request_t) - sizeof(mca_ptl_base_send_request_t), /* bytes required by ptl for a request */
|
2004-07-29 05:36:20 +04:00
|
|
|
0, /* max size of first fragment */
|
|
|
|
0, /* min fragment size */
|
|
|
|
0, /* max fragment size */
|
|
|
|
0, /* exclusivity */
|
|
|
|
0, /* latency */
|
|
|
|
0, /* bandwidth */
|
2004-05-20 17:45:34 +04:00
|
|
|
MCA_PTL_PUT, /* ptl flags */
|
2004-06-04 02:13:01 +04:00
|
|
|
mca_ptl_tcp_add_procs,
|
|
|
|
mca_ptl_tcp_del_procs,
|
2004-01-31 02:02:39 +03:00
|
|
|
mca_ptl_tcp_finalize,
|
2004-01-14 18:15:17 +03:00
|
|
|
mca_ptl_tcp_send,
|
2004-07-15 22:08:20 +04:00
|
|
|
mca_ptl_tcp_send,
|
2004-05-20 17:45:34 +04:00
|
|
|
NULL,
|
|
|
|
mca_ptl_tcp_matched,
|
2004-07-15 22:08:20 +04:00
|
|
|
mca_ptl_tcp_request_init,
|
2004-10-07 01:08:54 +04:00
|
|
|
mca_ptl_tcp_request_fini,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-08-12 01:35:31 +04:00
|
|
|
/*
|
|
|
|
* For each peer process:
|
|
|
|
* (1) Lookup/create a parallel structure that represents the TCP state of the peer process.
|
|
|
|
* (2) Use the mca_base_modex_recv function determine the endpoints exported by the peer.
|
|
|
|
* (3) Create a data structure to represent the state of the connection to the peer.
|
|
|
|
* (4) Select an address exported by the peer to use for this connection.
|
|
|
|
*/
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-06-04 02:13:01 +04:00
|
|
|
int mca_ptl_tcp_add_procs(
|
2004-08-02 04:24:22 +04:00
|
|
|
struct mca_ptl_base_module_t* ptl,
|
2004-06-04 02:13:01 +04:00
|
|
|
size_t nprocs,
|
2004-06-07 19:33:53 +04:00
|
|
|
struct ompi_proc_t **ompi_procs,
|
2004-06-04 02:13:01 +04:00
|
|
|
struct mca_ptl_base_peer_t** peers,
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_bitmap_t* reachable)
|
2004-01-16 03:34:05 +03:00
|
|
|
{
|
2004-06-04 02:13:01 +04:00
|
|
|
size_t i;
|
2004-08-11 20:56:45 +04:00
|
|
|
mca_ptl_tcp_module_t *ptl_tcp = (mca_ptl_tcp_module_t*)ptl;
|
2004-10-11 19:46:01 +04:00
|
|
|
struct ompi_proc_t * proc_self = ompi_proc_local();
|
2004-08-11 20:56:45 +04:00
|
|
|
|
2004-06-04 02:13:01 +04:00
|
|
|
for(i=0; i<nprocs; i++) {
|
2004-06-07 19:33:53 +04:00
|
|
|
struct ompi_proc_t *ompi_proc = ompi_procs[i];
|
2004-10-11 19:46:01 +04:00
|
|
|
mca_ptl_tcp_proc_t* ptl_proc;
|
2004-06-04 02:13:01 +04:00
|
|
|
mca_ptl_base_peer_t* ptl_peer;
|
|
|
|
int rc;
|
|
|
|
|
2004-10-11 19:46:01 +04:00
|
|
|
/* Dont let me register tcp for self */
|
|
|
|
if( proc_self == ompi_proc ) continue;
|
|
|
|
|
|
|
|
ptl_proc = mca_ptl_tcp_proc_create(ompi_proc);
|
2004-06-04 02:13:01 +04:00
|
|
|
if(NULL == ptl_proc)
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
2004-06-04 02:13:01 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to make sure that the peer has at least as many interface addresses
|
|
|
|
* exported as we are trying to use. If not, then don't bind this PTL instance
|
2004-08-12 01:35:31 +04:00
|
|
|
* to the proc, as we have already associated a PTL instance w/ each of the
|
|
|
|
* endpoints published by the peer.
|
2004-06-04 02:13:01 +04:00
|
|
|
*/
|
2004-06-25 01:39:08 +04:00
|
|
|
OMPI_THREAD_LOCK(&ptl_proc->proc_lock);
|
2004-06-04 02:13:01 +04:00
|
|
|
if(ptl_proc->proc_addr_count == ptl_proc->proc_peer_count) {
|
2005-04-10 04:26:35 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&ptl_proc->proc_lock);
|
|
|
|
continue;
|
|
|
|
}
|
2004-01-29 01:52:51 +03:00
|
|
|
|
2004-06-04 02:13:01 +04:00
|
|
|
/* The ptl_proc datastructure is shared by all TCP PTL instances that are trying
|
|
|
|
* to reach this destination. Cache the peer instance on the ptl_proc.
|
|
|
|
*/
|
|
|
|
ptl_peer = OBJ_NEW(mca_ptl_tcp_peer_t);
|
|
|
|
if(NULL == ptl_peer) {
|
2004-06-25 01:39:08 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&ptl_proc->proc_lock);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
2004-06-04 02:13:01 +04:00
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
ptl_peer->peer_ptl = (mca_ptl_tcp_module_t*)ptl;
|
2004-06-04 02:13:01 +04:00
|
|
|
rc = mca_ptl_tcp_proc_insert(ptl_proc, ptl_peer);
|
2004-06-07 19:33:53 +04:00
|
|
|
if(rc != OMPI_SUCCESS) {
|
2004-06-04 02:13:01 +04:00
|
|
|
OBJ_RELEASE(ptl_peer);
|
2004-06-25 01:39:08 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&ptl_proc->proc_lock);
|
2005-02-10 03:04:52 +03:00
|
|
|
continue; /* UNREACHABLE it's not a problem, others PTL can be used to send the data */
|
2004-06-04 02:13:01 +04:00
|
|
|
}
|
2004-10-13 01:50:25 +04:00
|
|
|
/* do we need to convert to/from network byte order */
|
|
|
|
if(ompi_proc->proc_arch != proc_self->proc_arch)
|
2004-11-18 01:47:08 +03:00
|
|
|
ptl_peer->peer_nbo = true;
|
2004-10-13 01:50:25 +04:00
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_bitmap_set_bit(reachable, i);
|
2004-06-25 01:39:08 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&ptl_proc->proc_lock);
|
2004-06-04 02:13:01 +04:00
|
|
|
peers[i] = ptl_peer;
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_append(&ptl_tcp->ptl_peers, (opal_list_item_t*)ptl_peer);
|
2005-04-21 18:58:25 +04:00
|
|
|
/* we increase the count of MPI users of the event library
|
|
|
|
once per peer, so that we are used until we aren't
|
|
|
|
connected to a peer */
|
2005-07-04 01:57:43 +04:00
|
|
|
opal_progress_event_increment();
|
2004-01-29 01:52:51 +03:00
|
|
|
}
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-16 03:34:05 +03:00
|
|
|
}
|
|
|
|
|
2004-08-11 20:56:45 +04:00
|
|
|
/*
|
2004-08-12 01:35:31 +04:00
|
|
|
* Cleanup the peer datastructure(s) - and remove the cooresponding
|
|
|
|
* tcp process data structure(s).
|
2004-08-11 20:56:45 +04:00
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_del_procs(struct mca_ptl_base_module_t* ptl, size_t nprocs, struct ompi_proc_t **procs, struct mca_ptl_base_peer_t ** peers)
|
2004-01-15 20:43:54 +03:00
|
|
|
{
|
2004-06-04 02:13:01 +04:00
|
|
|
size_t i;
|
2004-08-11 20:56:45 +04:00
|
|
|
mca_ptl_tcp_module_t *ptl_tcp = (mca_ptl_tcp_module_t*)ptl;
|
|
|
|
|
2004-06-04 02:13:01 +04:00
|
|
|
for(i=0; i<nprocs; i++) {
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_remove_item(&ptl_tcp->ptl_peers, (opal_list_item_t*)peers[i]);
|
2004-06-04 02:13:01 +04:00
|
|
|
OBJ_RELEASE(peers[i]);
|
2005-07-04 01:57:43 +04:00
|
|
|
opal_progress_event_decrement();
|
2004-06-04 02:13:01 +04:00
|
|
|
}
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|
2004-08-11 20:56:45 +04:00
|
|
|
/*
|
2004-08-12 01:35:31 +04:00
|
|
|
* Cleanup all peer data structures associated w/ the ptl.
|
2004-08-11 20:56:45 +04:00
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_finalize(struct mca_ptl_base_module_t* ptl)
|
2004-01-29 18:34:47 +03:00
|
|
|
{
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t* item;
|
2004-08-11 20:56:45 +04:00
|
|
|
mca_ptl_tcp_module_t *ptl_tcp = (mca_ptl_tcp_module_t*)ptl;
|
2005-07-03 20:22:16 +04:00
|
|
|
for( item = opal_list_remove_first(&ptl_tcp->ptl_peers);
|
2004-08-11 20:56:45 +04:00
|
|
|
item != NULL;
|
2005-07-03 20:22:16 +04:00
|
|
|
item = opal_list_remove_first(&ptl_tcp->ptl_peers)) {
|
2004-09-30 19:09:29 +04:00
|
|
|
mca_ptl_tcp_peer_t *peer = (mca_ptl_tcp_peer_t*)item;
|
|
|
|
OBJ_RELEASE(peer);
|
2005-07-04 01:57:43 +04:00
|
|
|
opal_progress_event_decrement();
|
2004-08-11 20:56:45 +04:00
|
|
|
}
|
2004-09-30 19:09:29 +04:00
|
|
|
free(ptl);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-29 18:34:47 +03:00
|
|
|
}
|
|
|
|
|
2004-08-11 20:56:45 +04:00
|
|
|
/*
|
2004-08-12 01:35:31 +04:00
|
|
|
* Initialize a request for use by the ptl. Use the extra memory allocated
|
|
|
|
* along w/ the ptl to cache the first fragment control information.
|
2004-08-11 20:56:45 +04:00
|
|
|
*/
|
|
|
|
|
2005-05-09 23:37:10 +04:00
|
|
|
int mca_ptl_tcp_request_init(struct mca_ptl_base_module_t* ptl, struct mca_ptl_base_send_request_t* request)
|
2004-01-29 18:34:47 +03:00
|
|
|
{
|
2004-07-15 22:08:20 +04:00
|
|
|
OBJ_CONSTRUCT(request+1, mca_ptl_tcp_send_frag_t);
|
2004-07-30 20:09:15 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-29 18:34:47 +03:00
|
|
|
}
|
|
|
|
|
2004-02-04 00:33:29 +03:00
|
|
|
|
2004-08-11 20:56:45 +04:00
|
|
|
/*
|
2004-08-12 01:35:31 +04:00
|
|
|
* Cleanup any resources cached along w/ the request.
|
2004-08-11 20:56:45 +04:00
|
|
|
*/
|
|
|
|
|
2005-05-09 23:37:10 +04:00
|
|
|
void mca_ptl_tcp_request_fini(struct mca_ptl_base_module_t* ptl, struct mca_ptl_base_send_request_t* request)
|
2004-01-29 22:27:39 +03:00
|
|
|
{
|
2004-07-15 22:08:20 +04:00
|
|
|
OBJ_DESTRUCT(request+1);
|
2004-01-29 22:27:39 +03:00
|
|
|
}
|
|
|
|
|
2004-02-04 00:33:29 +03:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
void mca_ptl_tcp_recv_frag_return(struct mca_ptl_base_module_t* ptl, struct mca_ptl_tcp_recv_frag_t* frag)
|
2004-02-04 00:33:29 +03:00
|
|
|
{
|
2005-03-26 21:49:16 +03:00
|
|
|
if(frag->frag_recv.frag_is_buffered) {
|
2004-07-15 22:08:20 +04:00
|
|
|
free(frag->frag_recv.frag_base.frag_addr);
|
2005-03-26 21:49:16 +03:00
|
|
|
frag->frag_recv.frag_is_buffered = false;
|
|
|
|
frag->frag_recv.frag_base.frag_addr = NULL;
|
|
|
|
}
|
2005-07-03 20:22:16 +04:00
|
|
|
OMPI_FREE_LIST_RETURN(&mca_ptl_tcp_component.tcp_recv_frags, (opal_list_item_t*)frag);
|
2004-02-04 00:33:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
void mca_ptl_tcp_send_frag_return(struct mca_ptl_base_module_t* ptl, struct mca_ptl_tcp_send_frag_t* frag)
|
2004-03-16 18:12:11 +03:00
|
|
|
{
|
2005-07-03 20:22:16 +04:00
|
|
|
if(opal_list_get_size(&mca_ptl_tcp_component.tcp_pending_acks)) {
|
2004-03-26 17:15:20 +03:00
|
|
|
mca_ptl_tcp_recv_frag_t* pending;
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_THREAD_LOCK(&mca_ptl_tcp_component.tcp_lock);
|
2005-07-03 20:22:16 +04:00
|
|
|
pending = (mca_ptl_tcp_recv_frag_t*)opal_list_remove_first(&mca_ptl_tcp_component.tcp_pending_acks);
|
2004-03-16 18:12:11 +03:00
|
|
|
if(NULL == pending) {
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2005-07-03 20:22:16 +04:00
|
|
|
OMPI_FREE_LIST_RETURN(&mca_ptl_tcp_component.tcp_send_frags, (opal_list_item_t*)frag);
|
2004-03-16 18:12:11 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-07-15 22:08:20 +04:00
|
|
|
mca_ptl_tcp_send_frag_init_ack(frag, ptl, pending->frag_recv.frag_base.frag_peer, pending);
|
2004-11-18 01:47:08 +03:00
|
|
|
if(frag->frag_send.frag_base.frag_peer->peer_nbo) {
|
2004-10-13 01:50:25 +04:00
|
|
|
MCA_PTL_BASE_ACK_HDR_HTON(frag->frag_send.frag_base.frag_header.hdr_ack);
|
|
|
|
}
|
2004-09-17 12:07:13 +04:00
|
|
|
mca_ptl_tcp_peer_send(pending->frag_recv.frag_base.frag_peer, frag, 0);
|
2004-03-16 18:12:11 +03:00
|
|
|
mca_ptl_tcp_recv_frag_return(ptl, pending);
|
|
|
|
} else {
|
2005-07-03 20:22:16 +04:00
|
|
|
OMPI_FREE_LIST_RETURN(&mca_ptl_tcp_component.tcp_send_frags, (opal_list_item_t*)frag);
|
2004-03-16 18:12:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/*
|
|
|
|
* Initiate a send. If this is the first fragment, use the fragment
|
|
|
|
* descriptor allocated with the send requests, otherwise obtain
|
|
|
|
* one from the free list. Initialize the fragment and foward
|
|
|
|
* on to the peer.
|
|
|
|
*/
|
2004-03-16 18:12:11 +03:00
|
|
|
|
2004-02-04 00:33:29 +03:00
|
|
|
int mca_ptl_tcp_send(
|
2004-08-02 04:24:22 +04:00
|
|
|
struct mca_ptl_base_module_t* ptl,
|
2004-02-05 03:50:37 +03:00
|
|
|
struct mca_ptl_base_peer_t* ptl_peer,
|
2005-05-09 23:37:10 +04:00
|
|
|
struct mca_ptl_base_send_request_t* sendreq,
|
2004-05-20 17:45:34 +04:00
|
|
|
size_t offset,
|
2004-06-04 02:13:01 +04:00
|
|
|
size_t size,
|
2004-03-16 18:12:11 +03:00
|
|
|
int flags)
|
2004-02-04 00:33:29 +03:00
|
|
|
{
|
|
|
|
mca_ptl_tcp_send_frag_t* sendfrag;
|
2004-05-20 17:45:34 +04:00
|
|
|
int rc;
|
2004-09-10 01:50:18 +04:00
|
|
|
if (offset == 0 && sendreq->req_cached) {
|
2004-02-04 00:33:29 +03:00
|
|
|
sendfrag = &((mca_ptl_tcp_send_request_t*)sendreq)->req_frag;
|
|
|
|
} else {
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t* item;
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_FREE_LIST_GET(&mca_ptl_tcp_component.tcp_send_frags, item, rc);
|
2004-05-19 01:06:11 +04:00
|
|
|
if(NULL == (sendfrag = (mca_ptl_tcp_send_frag_t*)item))
|
2004-02-04 00:33:29 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2004-06-04 02:13:01 +04:00
|
|
|
rc = mca_ptl_tcp_send_frag_init(sendfrag, ptl_peer, sendreq, offset, &size, flags);
|
2004-06-07 19:33:53 +04:00
|
|
|
if(rc != OMPI_SUCCESS)
|
2004-05-20 17:45:34 +04:00
|
|
|
return rc;
|
2004-06-04 02:13:01 +04:00
|
|
|
/* must update the offset after actual fragment size is determined -- and very important --
|
|
|
|
* before attempting to send the fragment
|
|
|
|
*/
|
2005-05-09 23:37:10 +04:00
|
|
|
mca_ptl_base_send_request_offset(sendreq, size);
|
2004-09-17 12:07:13 +04:00
|
|
|
return mca_ptl_tcp_peer_send(ptl_peer, sendfrag, offset);
|
2004-02-04 00:33:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/*
|
|
|
|
* A posted receive has been matched - if required send an
|
|
|
|
* ack back to the peer and process the fragment.
|
|
|
|
*/
|
|
|
|
|
2004-05-20 17:45:34 +04:00
|
|
|
void mca_ptl_tcp_matched(
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_base_module_t* ptl,
|
2004-03-26 17:15:20 +03:00
|
|
|
mca_ptl_base_recv_frag_t* frag)
|
2004-02-04 00:33:29 +03:00
|
|
|
{
|
2004-03-26 17:15:20 +03:00
|
|
|
/* send ack back to peer? */
|
2004-07-15 22:08:20 +04:00
|
|
|
mca_ptl_base_header_t* header = &frag->frag_base.frag_header;
|
2004-10-27 17:52:06 +04:00
|
|
|
if(header->hdr_common.hdr_flags & MCA_PTL_FLAGS_ACK) {
|
2004-03-16 18:12:11 +03:00
|
|
|
int rc;
|
2004-05-19 01:06:11 +04:00
|
|
|
mca_ptl_tcp_send_frag_t* ack;
|
2004-03-16 18:12:11 +03:00
|
|
|
mca_ptl_tcp_recv_frag_t* recv_frag = (mca_ptl_tcp_recv_frag_t*)frag;
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t* item;
|
2004-05-19 01:06:11 +04:00
|
|
|
MCA_PTL_TCP_SEND_FRAG_ALLOC(item, rc);
|
|
|
|
ack = (mca_ptl_tcp_send_frag_t*)item;
|
|
|
|
|
2004-03-16 18:12:11 +03:00
|
|
|
if(NULL == ack) {
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_THREAD_LOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-03-16 18:12:11 +03:00
|
|
|
recv_frag->frag_ack_pending = true;
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_append(&mca_ptl_tcp_component.tcp_pending_acks, (opal_list_item_t*)frag);
|
2004-08-02 04:24:22 +04:00
|
|
|
OMPI_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-03-16 18:12:11 +03:00
|
|
|
} else {
|
2004-07-15 22:08:20 +04:00
|
|
|
mca_ptl_tcp_send_frag_init_ack(ack, ptl, recv_frag->frag_recv.frag_base.frag_peer, recv_frag);
|
2004-11-18 01:47:08 +03:00
|
|
|
if(ack->frag_send.frag_base.frag_peer->peer_nbo) {
|
2004-10-13 01:50:25 +04:00
|
|
|
MCA_PTL_BASE_ACK_HDR_HTON(ack->frag_send.frag_base.frag_header.hdr_ack);
|
|
|
|
}
|
2004-09-17 12:07:13 +04:00
|
|
|
mca_ptl_tcp_peer_send(ack->frag_send.frag_base.frag_peer, ack, 0);
|
2004-03-12 01:02:01 +03:00
|
|
|
}
|
2004-02-10 19:53:41 +03:00
|
|
|
}
|
2004-03-12 01:02:01 +03:00
|
|
|
|
|
|
|
/* process fragment if complete */
|
2004-03-16 18:12:11 +03:00
|
|
|
mca_ptl_tcp_recv_frag_progress((mca_ptl_tcp_recv_frag_t*)frag);
|
2004-02-04 00:33:29 +03:00
|
|
|
}
|
|
|
|
|
2004-05-20 17:45:34 +04:00
|
|
|
|