2004-01-15 02:24:15 +03:00
|
|
|
/*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
#include "lam/util/output.h"
|
2004-01-15 20:43:54 +03:00
|
|
|
#include "lam/util/if.h"
|
2004-01-14 18:15:17 +03:00
|
|
|
#include "mca/mpi/pml/pml.h"
|
|
|
|
#include "mca/mpi/ptl/ptl.h"
|
2004-01-30 02:50:31 +03:00
|
|
|
#include "mca/mpi/ptl/base/ptl_base_sendreq.h"
|
2004-02-04 00:33:29 +03:00
|
|
|
#include "mca/mpi/ptl/base/ptl_base_sendfrag.h"
|
2004-01-29 01:52:51 +03:00
|
|
|
#include "mca/lam/base/mca_base_module_exchange.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-01-14 18:15:17 +03:00
|
|
|
|
|
|
|
|
|
|
|
mca_ptl_tcp_t mca_ptl_tcp = {
|
|
|
|
{
|
2004-01-15 03:58:54 +03:00
|
|
|
&mca_ptl_tcp_module.super,
|
2004-01-16 03:34:05 +03:00
|
|
|
0, /* ptl_exclusivity */
|
|
|
|
0, /* ptl_latency */
|
|
|
|
0, /* ptl_andwidth */
|
2004-01-14 18:15:17 +03:00
|
|
|
0, /* ptl_frag_first_size */
|
|
|
|
0, /* ptl_frag_min_size */
|
|
|
|
0, /* ptl_frag_max_size */
|
2004-01-15 20:43:54 +03:00
|
|
|
mca_ptl_tcp_add_proc,
|
2004-01-15 22:55:47 +03:00
|
|
|
mca_ptl_tcp_del_proc,
|
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-02-05 03:50:37 +03:00
|
|
|
mca_ptl_tcp_recv,
|
2004-01-29 22:27:39 +03:00
|
|
|
mca_ptl_tcp_request_alloc,
|
2004-02-04 00:33:29 +03:00
|
|
|
mca_ptl_tcp_request_return,
|
|
|
|
mca_ptl_tcp_frag_return
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
int mca_ptl_tcp_create(int if_index)
|
|
|
|
{
|
2004-02-10 03:09:36 +03:00
|
|
|
mca_ptl_tcp_t* ptl = malloc(sizeof(mca_ptl_tcp_t));
|
2004-01-16 03:34:05 +03:00
|
|
|
if(NULL == ptl)
|
2004-01-15 03:58:54 +03:00
|
|
|
return LAM_ERR_OUT_OF_RESOURCE;
|
|
|
|
memcpy(ptl, &mca_ptl_tcp, sizeof(mca_ptl_tcp));
|
|
|
|
mca_ptl_tcp_module.tcp_ptls[mca_ptl_tcp_module.tcp_num_ptls++] = ptl;
|
|
|
|
|
|
|
|
/* initialize the ptl */
|
2004-01-29 01:52:51 +03:00
|
|
|
ptl->ptl_ifindex = if_index;
|
|
|
|
lam_ifindextoaddr(if_index, (struct sockaddr*)&ptl->ptl_ifaddr, sizeof(ptl->ptl_ifaddr));
|
|
|
|
lam_ifindextomask(if_index, (struct sockaddr*)&ptl->ptl_ifmask, sizeof(ptl->ptl_ifmask));
|
2004-01-15 20:43:54 +03:00
|
|
|
return LAM_SUCCESS;
|
|
|
|
}
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-01-15 20:43:54 +03:00
|
|
|
|
2004-02-05 03:50:37 +03:00
|
|
|
int mca_ptl_tcp_add_proc(struct mca_ptl_t* ptl, struct lam_proc_t *lam_proc, struct mca_ptl_base_peer_t** peer_ret)
|
2004-01-16 03:34:05 +03:00
|
|
|
{
|
2004-01-29 01:52:51 +03:00
|
|
|
mca_ptl_tcp_proc_t* ptl_proc = mca_ptl_tcp_proc_create(lam_proc);
|
2004-02-05 03:50:37 +03:00
|
|
|
mca_ptl_base_peer_t* ptl_peer;
|
2004-01-29 01:52:51 +03:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
if(NULL == ptl_proc)
|
|
|
|
return LAM_ERR_OUT_OF_RESOURCE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
* to the proc.
|
|
|
|
*/
|
|
|
|
THREAD_LOCK(&ptl_proc->proc_lock);
|
|
|
|
if(ptl_proc->proc_addr_count == ptl_proc->proc_peer_count) {
|
|
|
|
THREAD_UNLOCK(&ptl_proc->proc_lock);
|
|
|
|
return LAM_ERR_UNREACH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
2004-02-10 19:53:41 +03:00
|
|
|
ptl_peer = OBJ_NEW(mca_ptl_tcp_peer_t);
|
2004-01-29 01:52:51 +03:00
|
|
|
if(NULL == ptl_peer) {
|
|
|
|
THREAD_UNLOCK(&ptl_proc->proc_lock);
|
|
|
|
return LAM_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
|
|
|
ptl_peer->peer_ptl = (mca_ptl_tcp_t*)ptl;
|
|
|
|
rc = mca_ptl_tcp_proc_insert(ptl_proc, ptl_peer);
|
|
|
|
if(rc != LAM_SUCCESS) {
|
|
|
|
OBJ_RELEASE(ptl_peer);
|
|
|
|
THREAD_UNLOCK(&ptl_proc->proc_lock);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
THREAD_UNLOCK(&ptl_proc->proc_lock);
|
|
|
|
*peer_ret = ptl_peer;
|
2004-01-16 03:34:05 +03:00
|
|
|
return LAM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-01-29 01:52:51 +03:00
|
|
|
|
2004-02-05 03:50:37 +03:00
|
|
|
int mca_ptl_tcp_del_proc(struct mca_ptl_t* ptl, struct lam_proc_t *proc, struct mca_ptl_base_peer_t* ptl_peer)
|
2004-01-15 20:43:54 +03:00
|
|
|
{
|
2004-01-29 01:52:51 +03:00
|
|
|
OBJ_RELEASE(ptl_peer);
|
2004-01-15 03:58:54 +03:00
|
|
|
return LAM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-01-31 02:02:39 +03:00
|
|
|
int mca_ptl_tcp_finalize(struct mca_ptl_t* ptl)
|
2004-01-29 18:34:47 +03:00
|
|
|
{
|
2004-02-10 03:09:36 +03:00
|
|
|
free(ptl);
|
2004-01-29 18:34:47 +03:00
|
|
|
return LAM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_ptl_tcp_request_alloc(struct mca_ptl_t* ptl, struct mca_ptl_base_send_request_t** request)
|
|
|
|
{
|
|
|
|
int rc;
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_base_send_request_t* sendreq =
|
|
|
|
(mca_ptl_base_send_request_t*)lam_free_list_get(&mca_ptl_tcp_module.tcp_send_requests, &rc);
|
|
|
|
if(NULL != sendreq)
|
|
|
|
sendreq->req_owner = ptl;
|
|
|
|
*request = sendreq;
|
2004-01-29 18:34:47 +03:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2004-02-04 00:33:29 +03:00
|
|
|
|
2004-01-29 22:27:39 +03:00
|
|
|
void mca_ptl_tcp_request_return(struct mca_ptl_t* ptl, struct mca_ptl_base_send_request_t* request)
|
|
|
|
{
|
|
|
|
lam_free_list_return(&mca_ptl_tcp_module.tcp_send_requests, (lam_list_item_t*)request);
|
|
|
|
}
|
|
|
|
|
2004-02-04 00:33:29 +03:00
|
|
|
|
|
|
|
void mca_ptl_tcp_frag_return(struct mca_ptl_t* ptl, struct mca_ptl_base_recv_frag_t* frag)
|
|
|
|
{
|
|
|
|
lam_free_list_return(&mca_ptl_tcp_module.tcp_recv_frags, (lam_list_item_t*)frag);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int mca_ptl_tcp_send(
|
|
|
|
struct mca_ptl_t* ptl,
|
2004-02-05 03:50:37 +03:00
|
|
|
struct mca_ptl_base_peer_t* ptl_peer,
|
2004-02-04 00:33:29 +03:00
|
|
|
struct mca_ptl_base_send_request_t* sendreq,
|
2004-02-05 20:12:59 +03:00
|
|
|
size_t size)
|
2004-02-04 00:33:29 +03:00
|
|
|
{
|
|
|
|
mca_ptl_tcp_send_frag_t* sendfrag;
|
|
|
|
if (sendreq->req_frags == 0) {
|
|
|
|
sendfrag = &((mca_ptl_tcp_send_request_t*)sendreq)->req_frag;
|
|
|
|
} else {
|
|
|
|
int rc;
|
|
|
|
sendfrag = (mca_ptl_tcp_send_frag_t*)lam_free_list_get(&mca_ptl_tcp_module.tcp_send_frags, &rc);
|
|
|
|
if(sendfrag == 0)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
mca_ptl_tcp_send_frag_reinit(sendfrag, ptl_peer, sendreq, size);
|
|
|
|
return mca_ptl_tcp_peer_send(ptl_peer, sendfrag);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-10 19:53:41 +03:00
|
|
|
void mca_ptl_tcp_recv(
|
2004-02-04 00:33:29 +03:00
|
|
|
struct mca_ptl_t* ptl,
|
|
|
|
struct mca_ptl_base_recv_frag_t* frag)
|
|
|
|
{
|
2004-02-10 19:53:41 +03:00
|
|
|
if(mca_ptl_tcp_recv_frag_cts((mca_ptl_tcp_recv_frag_t*)frag) == false) {
|
|
|
|
lam_list_append(&mca_ptl_tcp_module.tcp_acks, (lam_list_item_t*)frag);
|
|
|
|
}
|
2004-02-04 00:33:29 +03:00
|
|
|
}
|
|
|
|
|