2005-01-12 20:51:34 +00:00
|
|
|
#include "ompi_config.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
2005-03-14 20:57:21 +00:00
|
|
|
#ifdef HAVE_SYS_FCNTL_H
|
|
|
|
#include <sys/fcntl.h>
|
2005-01-12 20:51:34 +00:00
|
|
|
#endif
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include "util/output.h"
|
2005-03-14 20:57:21 +00:00
|
|
|
#include "mca/rml/rml.h"
|
2005-01-12 20:51:34 +00:00
|
|
|
#include "mca/iof/base/base.h"
|
2005-03-14 20:57:21 +00:00
|
|
|
#include "iof_base_endpoint.h"
|
|
|
|
#include "iof_base_fragment.h"
|
2005-01-12 20:51:34 +00:00
|
|
|
|
|
|
|
/**
|
2005-01-13 15:27:28 +00:00
|
|
|
* Construct/Destructor
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static void orte_iof_base_endpoint_construct(orte_iof_base_endpoint_t* endpoint)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
|
|
|
endpoint->ep_mode = 0;
|
2005-03-14 20:57:21 +00:00
|
|
|
endpoint->ep_state = ORTE_IOF_EP_CLOSED;
|
2005-01-12 20:51:34 +00:00
|
|
|
endpoint->ep_seq = 0;
|
|
|
|
endpoint->ep_ack = 0;
|
|
|
|
memset(&endpoint->ep_event,0,sizeof(endpoint->ep_event));
|
|
|
|
OBJ_CONSTRUCT(&endpoint->ep_frags, ompi_list_t);
|
|
|
|
}
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static void orte_iof_base_endpoint_destruct(orte_iof_base_endpoint_t* endpoint)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
if(endpoint->ep_fd > 0) {
|
|
|
|
ompi_event_del(&endpoint->ep_event);
|
|
|
|
}
|
2005-01-12 20:51:34 +00:00
|
|
|
OBJ_DESTRUCT(&endpoint->ep_frags);
|
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t,
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_list_item_t,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_construct,
|
|
|
|
orte_iof_base_endpoint_destruct);
|
2005-01-12 20:51:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Callback when non-blocking OOB send completes.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static void orte_iof_base_endpoint_send_cb(
|
2005-01-12 20:51:34 +00:00
|
|
|
int status,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_process_name_t* peer,
|
2005-01-12 20:51:34 +00:00
|
|
|
struct iovec* msg,
|
|
|
|
int count,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_rml_tag_t tag,
|
2005-01-12 20:51:34 +00:00
|
|
|
void* cbdata)
|
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_frag_t* frag = (orte_iof_base_frag_t*)cbdata;
|
|
|
|
orte_iof_base_endpoint_t* endpoint = frag->frag_owner;
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_list_remove_item(&endpoint->ep_frags, &frag->super);
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_FRAG_RETURN(frag);
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Callback when data is available on the endpoint to read.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static void orte_iof_base_endpoint_read_handler(int fd, short flags, void *cbdata)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)cbdata;
|
|
|
|
orte_iof_base_frag_t* frag;
|
|
|
|
orte_iof_base_header_t* hdr;
|
2005-01-12 20:51:34 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
/* allocate a fragment */
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_FRAG_ALLOC(frag,rc);
|
2005-01-12 20:51:34 +00:00
|
|
|
if(NULL == frag) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
frag->frag_owner = endpoint;
|
|
|
|
ompi_list_append(&endpoint->ep_frags, &frag->super);
|
|
|
|
|
|
|
|
/* read up to the fragment size */
|
|
|
|
rc = read(fd, frag->frag_data, sizeof(frag->frag_data));
|
|
|
|
if(rc <= 0) {
|
2005-01-13 15:27:28 +00:00
|
|
|
/* non-blocking */
|
|
|
|
if(rc < 0 && errno == EAGAIN) {
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_FRAG_RETURN(frag);
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-13 15:27:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-01-12 20:51:34 +00:00
|
|
|
/* peer has closed the connection */
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_closed(endpoint);
|
2005-01-12 20:51:34 +00:00
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
frag->frag_iov[1].iov_len = frag->frag_len = rc;
|
|
|
|
|
|
|
|
/* fill in the header */
|
|
|
|
hdr = &frag->frag_hdr;
|
2005-03-14 20:57:21 +00:00
|
|
|
hdr->hdr_common.hdr_type = ORTE_IOF_BASE_HDR_MSG;
|
2005-01-12 20:51:34 +00:00
|
|
|
hdr->hdr_msg.msg_src = endpoint->ep_name;
|
2005-03-29 19:40:38 +00:00
|
|
|
hdr->hdr_msg.msg_proxy = *ORTE_RML_NAME_SELF;
|
2005-01-12 20:51:34 +00:00
|
|
|
hdr->hdr_msg.msg_tag = endpoint->ep_tag;
|
|
|
|
hdr->hdr_msg.msg_seq = endpoint->ep_seq;
|
|
|
|
hdr->hdr_msg.msg_len = frag->frag_len;
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_HDR_MSG_HTON(hdr->hdr_msg);
|
2005-01-12 20:51:34 +00:00
|
|
|
|
|
|
|
/* if window size has been exceeded - disable forwarding */
|
|
|
|
endpoint->ep_seq += frag->frag_len;
|
2005-03-14 20:57:21 +00:00
|
|
|
if(ORTE_IOF_BASE_SEQDIFF(endpoint->ep_seq,endpoint->ep_ack) > orte_iof_base.iof_window_size) {
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_event_del(&endpoint->ep_event);
|
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
|
|
|
|
/* start non-blocking OOB call to forward received data */
|
2005-03-14 20:57:21 +00:00
|
|
|
rc = orte_rml.send_nb(
|
|
|
|
orte_iof_base.iof_service,
|
2005-01-12 20:51:34 +00:00
|
|
|
frag->frag_iov,
|
|
|
|
2,
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_RML_TAG_IOF_SVC,
|
2005-01-12 20:51:34 +00:00
|
|
|
0,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_send_cb,
|
2005-01-12 20:51:34 +00:00
|
|
|
frag);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-13 15:27:28 +00:00
|
|
|
/**
|
|
|
|
* Callback when the endpoint is available for write.
|
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static void orte_iof_base_endpoint_write_handler(int sd, short flags, void *user)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)user;
|
2005-01-13 15:27:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* step through the list of queued fragments and attempt to write
|
|
|
|
* until the output descriptor would block
|
|
|
|
*/
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
while(ompi_list_get_size(&endpoint->ep_frags)) {
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_frag_t* frag = (orte_iof_base_frag_t*)ompi_list_get_first(&endpoint->ep_frags);
|
2005-01-12 20:51:34 +00:00
|
|
|
int rc = write(endpoint->ep_fd, frag->frag_ptr, frag->frag_len);
|
|
|
|
if(rc < 0) {
|
2005-01-13 15:27:28 +00:00
|
|
|
if(errno == EAGAIN)
|
|
|
|
break;
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_closed(endpoint);
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
frag->frag_len -= rc;
|
|
|
|
frag->frag_ptr += rc;
|
|
|
|
if(frag->frag_len > 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ompi_list_remove_item(&endpoint->ep_frags, &frag->super);
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_frag_ack(frag);
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* is there anything left to write? */
|
|
|
|
if(ompi_list_get_size(&endpoint->ep_frags) == 0) {
|
|
|
|
ompi_event_del(&endpoint->ep_event);
|
2005-03-14 20:57:21 +00:00
|
|
|
if(orte_iof_base.iof_waiting) {
|
|
|
|
ompi_condition_signal(&orte_iof_base.iof_condition);
|
2005-01-14 00:11:24 +00:00
|
|
|
}
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Lookup existing endpoint matching parameters
|
|
|
|
* supplied to create.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
static orte_iof_base_endpoint_t* orte_iof_base_endpoint_lookup(
|
|
|
|
const orte_process_name_t* proc,
|
|
|
|
orte_iof_base_mode_t mode,
|
2005-01-12 20:51:34 +00:00
|
|
|
int tag)
|
|
|
|
{
|
2005-03-29 19:40:38 +00:00
|
|
|
ompi_list_item_t* item;
|
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
|
|
|
for(item = ompi_list_get_first(&orte_iof_base.iof_endpoints);
|
|
|
|
item != ompi_list_get_end(&orte_iof_base.iof_endpoints);
|
|
|
|
item = ompi_list_get_next(item)) {
|
|
|
|
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)item;
|
|
|
|
if(orte_ns.compare(ORTE_NS_CMP_ALL,proc,&endpoint->ep_name) == 0 &&
|
|
|
|
endpoint->ep_tag == tag && endpoint->ep_mode == mode) {
|
|
|
|
OBJ_RETAIN(endpoint);
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
|
|
|
return endpoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Create a local endpoint.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
int orte_iof_base_endpoint_create(
|
|
|
|
const orte_process_name_t* proc,
|
|
|
|
orte_iof_base_mode_t mode,
|
2005-01-12 20:51:34 +00:00
|
|
|
int tag,
|
|
|
|
int fd)
|
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t* endpoint;
|
2005-01-12 20:51:34 +00:00
|
|
|
int flags;
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
|
|
|
if((endpoint = orte_iof_base_endpoint_lookup(proc,mode,tag)) != NULL) {
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return OMPI_EXISTS;
|
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
endpoint = OBJ_NEW(orte_iof_base_endpoint_t);
|
2005-01-12 20:51:34 +00:00
|
|
|
if(NULL == endpoint) {
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
|
|
|
endpoint->ep_name = *proc;
|
|
|
|
endpoint->ep_mode = mode;
|
|
|
|
endpoint->ep_tag = tag;
|
|
|
|
endpoint->ep_fd = fd;
|
|
|
|
|
|
|
|
/* set file descriptor to be non-blocking */
|
|
|
|
if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
|
2005-03-14 20:57:21 +00:00
|
|
|
ompi_output(0, "orte_iof_base_endpoint_create: fcntl(F_GETFL) failed with errno=%d\n", errno);
|
2005-01-12 20:51:34 +00:00
|
|
|
} else {
|
|
|
|
flags |= O_NONBLOCK;
|
|
|
|
fcntl(fd, F_SETFL, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup event handler */
|
|
|
|
switch(mode) {
|
2005-03-14 20:57:21 +00:00
|
|
|
case ORTE_IOF_SOURCE:
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_event_set(
|
|
|
|
&endpoint->ep_event,
|
|
|
|
endpoint->ep_fd,
|
|
|
|
OMPI_EV_READ|OMPI_EV_PERSIST,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_read_handler,
|
2005-01-12 20:51:34 +00:00
|
|
|
endpoint);
|
|
|
|
ompi_event_add(&endpoint->ep_event, 0);
|
|
|
|
break;
|
2005-03-14 20:57:21 +00:00
|
|
|
case ORTE_IOF_SINK:
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_event_set(
|
|
|
|
&endpoint->ep_event,
|
|
|
|
endpoint->ep_fd,
|
2005-01-13 15:27:28 +00:00
|
|
|
OMPI_EV_WRITE|OMPI_EV_PERSIST,
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_write_handler,
|
2005-01-12 20:51:34 +00:00
|
|
|
endpoint);
|
|
|
|
break;
|
|
|
|
default:
|
2005-03-14 20:57:21 +00:00
|
|
|
ompi_output(0, "orte_iof_base_endpoint_create: invalid mode %d\n", mode);
|
2005-01-12 20:51:34 +00:00
|
|
|
return OMPI_ERR_BAD_PARAM;
|
|
|
|
}
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
ompi_list_append(&orte_iof_base.iof_endpoints, &endpoint->super);
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-03-29 19:40:38 +00:00
|
|
|
return ORTE_SUCCESS;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Close one or more matching endpoints.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
int orte_iof_base_endpoint_delete(
|
|
|
|
const orte_process_name_t* proc,
|
|
|
|
orte_ns_cmp_bitmask_t mask,
|
2005-01-12 20:51:34 +00:00
|
|
|
int tag)
|
|
|
|
{
|
2005-03-29 19:40:38 +00:00
|
|
|
ompi_list_item_t* item;
|
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
|
|
|
item = ompi_list_get_first(&orte_iof_base.iof_endpoints);
|
|
|
|
while(item != ompi_list_get_end(&orte_iof_base.iof_endpoints)) {
|
|
|
|
ompi_list_item_t* next = ompi_list_get_next(item);
|
|
|
|
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)item;
|
|
|
|
if(orte_ns.compare(mask,proc,&endpoint->ep_name) == 0 &&
|
|
|
|
endpoint->ep_tag == tag) {
|
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
ompi_list_remove_item(&orte_iof_base.iof_endpoints,&endpoint->super);
|
|
|
|
}
|
|
|
|
item = next;
|
|
|
|
}
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
|
|
|
return ORTE_ERR_NOT_FOUND;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
int orte_iof_base_endpoint_close(orte_iof_base_endpoint_t* endpoint)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
endpoint->ep_state = ORTE_IOF_EP_CLOSING;
|
2005-01-12 20:51:34 +00:00
|
|
|
switch(endpoint->ep_mode) {
|
2005-03-14 20:57:21 +00:00
|
|
|
case ORTE_IOF_SOURCE:
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_event_del(&endpoint->ep_event);
|
|
|
|
if(endpoint->ep_seq == endpoint->ep_ack) {
|
2005-03-14 20:57:21 +00:00
|
|
|
endpoint->ep_state = ORTE_IOF_EP_CLOSED;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-03-14 20:57:21 +00:00
|
|
|
case ORTE_IOF_SINK:
|
2005-01-12 20:51:34 +00:00
|
|
|
if(ompi_list_get_size(&endpoint->ep_frags) == 0) {
|
2005-03-14 20:57:21 +00:00
|
|
|
endpoint->ep_state = ORTE_IOF_EP_CLOSED;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-03-29 19:40:38 +00:00
|
|
|
return ORTE_SUCCESS;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Peer has gone away - cleanup and signal SOH monitor.
|
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
void orte_iof_base_endpoint_closed(orte_iof_base_endpoint_t* endpoint)
|
2005-01-12 20:51:34 +00:00
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_close(endpoint);
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Lookup endpoint based on destination process name/mask/tag.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t* orte_iof_base_endpoint_match(
|
|
|
|
const orte_process_name_t* dst_name,
|
|
|
|
orte_ns_cmp_bitmask_t dst_mask,
|
2005-01-12 20:51:34 +00:00
|
|
|
int dst_tag)
|
|
|
|
{
|
|
|
|
ompi_list_item_t* item;
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
|
|
|
for(item = ompi_list_get_first(&orte_iof_base.iof_endpoints);
|
|
|
|
item != ompi_list_get_end(&orte_iof_base.iof_endpoints);
|
2005-01-12 20:51:34 +00:00
|
|
|
item = ompi_list_get_next(item)) {
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)item;
|
|
|
|
if(orte_ns.compare(dst_mask,dst_name,&endpoint->ep_name) == 0) {
|
|
|
|
if(endpoint->ep_tag == dst_tag || endpoint->ep_tag == ORTE_IOF_ANY || dst_tag == ORTE_IOF_ANY) {
|
2005-01-12 20:51:34 +00:00
|
|
|
OBJ_RETAIN(endpoint);
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return endpoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-01-13 15:27:28 +00:00
|
|
|
* Forward data out the endpoint as the destination
|
|
|
|
* is available. Queue incomplete fragments in order
|
|
|
|
* received and process as the destination becomes available.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
int orte_iof_base_endpoint_forward(
|
|
|
|
orte_iof_base_endpoint_t* endpoint,
|
|
|
|
const orte_process_name_t* src,
|
|
|
|
orte_iof_base_msg_header_t* hdr,
|
2005-01-12 20:51:34 +00:00
|
|
|
const unsigned char* data)
|
|
|
|
{
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_frag_t* frag;
|
2005-01-12 20:51:34 +00:00
|
|
|
size_t len = hdr->msg_len;
|
|
|
|
int rc = 0;
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
if(endpoint->ep_mode != ORTE_IOF_SINK) {
|
2005-01-13 15:27:28 +00:00
|
|
|
return OMPI_ERR_BAD_PARAM;
|
|
|
|
}
|
|
|
|
|
2005-01-12 20:51:34 +00:00
|
|
|
/* allocate and initialize a fragment */
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_FRAG_ALLOC(frag, rc);
|
2005-01-12 20:51:34 +00:00
|
|
|
if(NULL == frag) {
|
2005-01-13 15:27:28 +00:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
2005-01-13 15:27:28 +00:00
|
|
|
endpoint->ep_seq = hdr->msg_seq + hdr->msg_len;
|
2005-01-12 20:51:34 +00:00
|
|
|
frag->frag_owner = endpoint;
|
|
|
|
frag->frag_src = *src;
|
|
|
|
frag->frag_hdr.hdr_msg = *hdr;
|
|
|
|
|
|
|
|
/* try to write w/out copying data */
|
|
|
|
if(ompi_list_get_size(&endpoint->ep_frags) == 0) {
|
|
|
|
rc = write(endpoint->ep_fd,data,len);
|
|
|
|
if(rc < 0) {
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_endpoint_closed(endpoint);
|
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-03-29 19:40:38 +00:00
|
|
|
return ORTE_SUCCESS;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
frag->frag_len = len - rc;
|
|
|
|
if(frag->frag_len > 0) {
|
|
|
|
/* handle incomplete write */
|
|
|
|
frag->frag_ptr = frag->frag_data;
|
|
|
|
memcpy(frag->frag_ptr, data+rc, frag->frag_len);
|
|
|
|
ompi_list_append(&endpoint->ep_frags, &frag->super);
|
|
|
|
if(ompi_list_get_size(&endpoint->ep_frags) == 1) {
|
|
|
|
ompi_event_add(&endpoint->ep_event,0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* acknowledge fragment */
|
2005-03-29 19:40:38 +00:00
|
|
|
orte_iof_base_endpoint_ack(endpoint, frag->frag_hdr.hdr_msg.msg_seq + frag->frag_hdr.hdr_msg.msg_len);
|
2005-03-14 20:57:21 +00:00
|
|
|
orte_iof_base_frag_ack(frag);
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-03-29 19:40:38 +00:00
|
|
|
return ORTE_SUCCESS;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2005-01-13 15:27:28 +00:00
|
|
|
* Update the acknowledged sequence number. If forwarding had
|
|
|
|
* previously been disabled as the window closed, and the window
|
|
|
|
* is now open, re-enable forwarding.
|
2005-01-12 20:51:34 +00:00
|
|
|
*/
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
int orte_iof_base_endpoint_ack(
|
|
|
|
orte_iof_base_endpoint_t* endpoint,
|
2005-01-12 20:51:34 +00:00
|
|
|
uint32_t seq)
|
|
|
|
{
|
|
|
|
bool window_closed, window_open;
|
|
|
|
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_LOCK(&orte_iof_base.iof_lock);
|
2005-01-12 20:51:34 +00:00
|
|
|
window_closed =
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_SEQDIFF(endpoint->ep_seq,endpoint->ep_ack) >= orte_iof_base.iof_window_size;
|
2005-01-12 20:51:34 +00:00
|
|
|
endpoint->ep_ack = seq;
|
|
|
|
window_open =
|
2005-03-14 20:57:21 +00:00
|
|
|
ORTE_IOF_BASE_SEQDIFF(endpoint->ep_seq,endpoint->ep_ack) < orte_iof_base.iof_window_size;
|
2005-01-12 20:51:34 +00:00
|
|
|
|
2005-01-14 00:11:24 +00:00
|
|
|
/* someone is waiting on all output to be flushed */
|
2005-03-14 20:57:21 +00:00
|
|
|
if(orte_iof_base.iof_waiting && endpoint->ep_seq == endpoint->ep_ack) {
|
|
|
|
ompi_condition_signal(&orte_iof_base.iof_condition);
|
2005-01-14 00:11:24 +00:00
|
|
|
}
|
2005-01-12 20:51:34 +00:00
|
|
|
|
2005-01-14 00:11:24 +00:00
|
|
|
/* check to see if we need to reenable forwarding */
|
|
|
|
if(window_closed && window_open) {
|
2005-01-12 20:51:34 +00:00
|
|
|
ompi_event_add(&endpoint->ep_event, 0);
|
|
|
|
}
|
2005-03-14 20:57:21 +00:00
|
|
|
OMPI_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
2005-03-29 19:40:38 +00:00
|
|
|
return ORTE_SUCCESS;
|
2005-01-12 20:51:34 +00:00
|
|
|
}
|
|
|
|
|