-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/channels/sock/src/ch3_istartmsgv.c
        -:    0:Graph:ch3_istartmsgv.gcno
        -:    0:Data:ch3_istartmsgv.gcda
        -:    0:Runs:4381
        -:    0:Programs:1376
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpidi_ch3_impl.h"
        -:    8:
        -:    9:#undef FUNCNAME
        -:   10:#define FUNCNAME create_request
        -:   11:#undef FCNAME
        -:   12:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   13:static MPID_Request * create_request(MPID_IOV * iov, int iov_count, 
        -:   14:				     int iov_offset, MPIU_Size_t nb)
    11020:   15:{
        -:   16:    MPID_Request * sreq;
        -:   17:    int i;
        -:   18:    MPIDI_STATE_DECL(MPID_STATE_CREATE_REQUEST);
        -:   19:
        -:   20:    MPIDI_FUNC_ENTER(MPID_STATE_CREATE_REQUEST);
        -:   21:    
    11020:   22:    sreq = MPID_Request_create();
        -:   23:    /* --BEGIN ERROR HANDLING-- */
    11020:   24:    if (sreq == NULL)
    #####:   25:	return NULL;
        -:   26:    /* --END ERROR HANDLING-- */
    11020:   27:    MPIU_Object_set_ref(sreq, 2);
    11020:   28:    sreq->kind = MPID_REQUEST_SEND;
        -:   29:    
    33060:   30:    for (i = 0; i < iov_count; i++)
        -:   31:    {
    22040:   32:	sreq->dev.iov[i] = iov[i];
        -:   33:    }
    11020:   34:    if (iov_offset == 0)
        -:   35:    {
     1174:   36:	MPIU_Assert(iov[0].MPID_IOV_LEN == sizeof(MPIDI_CH3_Pkt_t));
     1174:   37:	sreq->dev.pending_pkt = *(MPIDI_CH3_PktGeneric_t *) iov[0].MPID_IOV_BUF;
     1174:   38:	sreq->dev.iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) &sreq->dev.pending_pkt;
        -:   39:    }
    11020:   40:    sreq->dev.iov[iov_offset].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)((char *) sreq->dev.iov[iov_offset].MPID_IOV_BUF + nb);
    11020:   41:    sreq->dev.iov[iov_offset].MPID_IOV_LEN -= nb;
    11020:   42:    sreq->dev.iov_count = iov_count;
    11020:   43:    sreq->dev.OnDataAvail = 0;
        -:   44:
        -:   45:    MPIDI_FUNC_EXIT(MPID_STATE_CREATE_REQUEST);
    11020:   46:    return sreq;
        -:   47:}
        -:   48:
        -:   49:/*
        -:   50: * MPIDI_CH3_iStartMsgv() attempts to send the message immediately.  If the 
        -:   51: * entire message is successfully sent, then NULL is
        -:   52: * returned.  Otherwise a request is allocated, the iovec and the first buffer 
        -:   53: * pointed to by the iovec (which is assumed to be a
        -:   54: * MPIDI_CH3_Pkt_t) are copied into the request, and a pointer to the request 
        -:   55: * is returned.  An error condition also results in a
        -:   56: * request be allocated and the errror being returned in the status field of 
        -:   57: * the request.
        -:   58: */
        -:   59:
        -:   60:/* XXX - What do we do if MPID_Request_create() returns NULL???  
        -:   61:   If MPIDI_CH3_iStartMsgv() returns NULL, the calling code
        -:   62:   assumes the request completely successfully, but the reality is that we 
        -:   63:   couldn't allocate the memory for a request.  This
        -:   64:   seems like a flaw in the CH3 API. */
        -:   65:
        -:   66:/* NOTE - The completion action associated with a request created by 
        -:   67:   CH3_iStartMsgv() is alway MPIDI_CH3_CA_COMPLETE.  This
        -:   68:   implies that CH3_iStartMsgv() can only be used when the entire message can 
        -:   69:   be described by a single iovec of size
        -:   70:   MPID_IOV_LIMIT. */
        -:   71:    
        -:   72:#undef FUNCNAME
        -:   73:#define FUNCNAME MPIDI_CH3_iStartMsgv
        -:   74:#undef FCNAME
        -:   75:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   76:int MPIDI_CH3_iStartMsgv(MPIDI_VC_t * vc, MPID_IOV * iov, int n_iov, 
        -:   77:			 MPID_Request ** sreq_ptr)
  2700500:   78:{
  2700500:   79:    MPID_Request * sreq = NULL;
  2700500:   80:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)vc->channel_private;
  2700500:   81:    int mpi_errno = MPI_SUCCESS;
        -:   82:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_ISTARTMSGV);
        -:   83:
        -:   84:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_ISTARTMSGV);
        -:   85:
  2700500:   86:    MPIU_Assert( n_iov <= MPID_IOV_LIMIT);
        -:   87:
        -:   88:    /* The SOCK channel uses a fixed length header, the size of which is the 
        -:   89:       maximum of all possible packet headers */
  2700500:   90:    iov[0].MPID_IOV_LEN = sizeof(MPIDI_CH3_Pkt_t);
        -:   91:    MPIU_DBG_STMT(CH3_CHANNEL,VERBOSE,
        -:   92:	   MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t*)iov[0].MPID_IOV_BUF));
        -:   93:    
  2700500:   94:    if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTED) /* MT */
        -:   95:    {
        -:   96:	/* Connection already formed.  If send queue is empty attempt to send 
        -:   97:	   data, queuing any unsent data. */
  2699771:   98:	if (MPIDI_CH3I_SendQ_empty(vcch)) /* MT */
        -:   99:	{
        -:  100:	    int rc;
        -:  101:	    MPIU_Size_t nb;
        -:  102:
        -:  103:	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:  104:			 "send queue empty, attempting to write");
        -:  105:	    MPIU_DBG_PKT(vcch->conn,(MPIDI_CH3_Pkt_t*)iov[0].MPID_IOV_BUF,"isend");
        -:  106:	    
        -:  107:	    /* MT - need some signalling to lock down our right to use the 
        -:  108:	       channel, thus insuring that the progress engine does
        -:  109:               also try to write */
  2699409:  110:	    rc = MPIDU_Sock_writev(vcch->sock, iov, n_iov, &nb);
  2699409:  111:	    if (rc == MPI_SUCCESS)
        -:  112:	    {
  2699409:  113:		int offset = 0;
        -:  114:    
        -:  115:		MPIU_DBG_MSG_D(CH3_CHANNEL,VERBOSE,
        -:  116:			       "wrote %ld bytes", (unsigned long) nb);
        -:  117:		
 10788538:  118:		while (offset < n_iov)
        -:  119:		{
  5399649:  120:		    if (nb >= (int)iov[offset].MPID_IOV_LEN)
        -:  121:		    {
  5389720:  122:			nb -= iov[offset].MPID_IOV_LEN;
  5389720:  123:			offset++;
        -:  124:		    }
        -:  125:		    else
        -:  126:		    {
        -:  127:			MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:  128:			     "partial write, request enqueued at head");
     9929:  129:			sreq = create_request(iov, n_iov, offset, nb);
     9929:  130:			if (sreq == NULL) {
    #####:  131:			    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  132:			}
     9929:  133:			MPIDI_CH3I_SendQ_enqueue_head(vcch, sreq);
        -:  134:			MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,
        -:  135:					 (MPIU_DBG_FDEST,"posting writev, vc=0x%p, sreq=0x%08x", vc, sreq->handle));
     9929:  136:			vcch->conn->send_active = sreq;
     9929:  137:			mpi_errno = MPIDU_Sock_post_writev(vcch->conn->sock, sreq->dev.iov + offset,
        -:  138:							   sreq->dev.iov_count - offset, NULL);
        -:  139:			/* --BEGIN ERROR HANDLING-- */
     9929:  140:			if (mpi_errno != MPI_SUCCESS)
        -:  141:			{
    #####:  142:			    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  143:							     "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p",
        -:  144:							     sreq, vcch->conn, vc);
        -:  145:			}
        -:  146:			/* --END ERROR HANDLING-- */
        -:  147:			break;
        -:  148:		    }
        -:  149:		}
        -:  150:
        -:  151:		if (offset == n_iov)
        -:  152:		{
        -:  153:		    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"entire write complete");
        -:  154:		}
        -:  155:	    }
        -:  156:	    /* --BEGIN ERROR HANDLING-- */
        -:  157:	    else
        -:  158:	    {
        -:  159:		MPIU_DBG_MSG_D(CH3_CHANNEL,TYPICAL,
        -:  160:			       "ERROR - MPIDU_Sock_writev failed, rc=%d", rc);
    #####:  161:		sreq = MPID_Request_create();
    #####:  162:		if (sreq == NULL) {
    #####:  163:		    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  164:		}
    #####:  165:		sreq->kind = MPID_REQUEST_SEND;
    #####:  166:		sreq->cc = 0;
    #####:  167:		sreq->status.MPI_ERROR = MPIR_Err_create_code( rc,
        -:  168:			       MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  169:			       MPI_ERR_INTERN, "**ch3|sock|writefailed", 
        -:  170:			       "**ch3|sock|writefailed %d", rc );
        -:  171:		/* Make sure that the caller sees this error */
    #####:  172:		mpi_errno = sreq->status.MPI_ERROR;
        -:  173:	    }
        -:  174:	    /* --END ERROR HANDLING-- */
        -:  175:	}
        -:  176:	else
        -:  177:	{
        -:  178:	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:  179:			 "send in progress, request enqueued");
      362:  180:	    sreq = create_request(iov, n_iov, 0, 0);
      362:  181:	    if (sreq == NULL) {
    #####:  182:		MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  183:	    }
      362:  184:	    MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  185:	}
        -:  186:    }
      729:  187:    else if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTING)
        -:  188:    {
        -:  189:	MPIU_DBG_VCUSE(vc,
        -:  190:		       "connecting.  enqueuing request");
        -:  191:	
        -:  192:	/* queue the data so it can be sent after the connection is formed */
    #####:  193:	sreq = create_request(iov, n_iov, 0, 0);
    #####:  194:	if (sreq == NULL) {
    #####:  195:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  196:	}
    #####:  197:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  198:    }
      729:  199:    else if (vcch->state == MPIDI_CH3I_VC_STATE_UNCONNECTED)
        -:  200:    {
        -:  201:	MPIU_DBG_VCUSE(vc,
        -:  202:		       "unconnected.  posting connect and enqueuing request");
        -:  203:	
        -:  204:	/* queue the data so it can be sent after the connection is formed */
      729:  205:	sreq = create_request(iov, n_iov, 0, 0);
      729:  206:	if (sreq == NULL) {
    #####:  207:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  208:	}
      729:  209:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  210:	
        -:  211:	/* Form a new connection */
      729:  212:	MPIDI_CH3I_VC_post_connect(vc);
        -:  213:    }
    #####:  214:    else if (vcch->state != MPIDI_CH3I_VC_STATE_FAILED)
        -:  215:    {
        -:  216:	/* Unable to send data at the moment, so queue it for later */
        -:  217:	MPIU_DBG_VCUSE(vc,"forming connection, request enqueued");
    #####:  218:	sreq = create_request(iov, n_iov, 0, 0);
    #####:  219:	if (sreq == NULL) {
    #####:  220:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  221:	}
    #####:  222:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  223:    }
        -:  224:    /* --BEGIN ERROR HANDLING-- */
        -:  225:    else
        -:  226:    {
        -:  227:	/* Connection failed, so allocate a request and return an error. */
        -:  228:	MPIU_DBG_VCUSE(vc,"ERROR - connection failed");
    #####:  229:	sreq = MPID_Request_create();
    #####:  230:	if (sreq == NULL) {
    #####:  231:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");
        -:  232:	}
    #####:  233:	sreq->kind = MPID_REQUEST_SEND;
    #####:  234:	sreq->cc = 0;
    #####:  235:	sreq->status.MPI_ERROR = MPIR_Err_create_code( MPI_SUCCESS,
        -:  236:		       MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  237:		       MPI_ERR_INTERN, "**ch3|sock|connectionfailed",0 );
        -:  238:	/* Make sure that the caller sees this error */
    #####:  239:	mpi_errno = sreq->status.MPI_ERROR;
        -:  240:    }
        -:  241:    /* --END ERROR HANDLING-- */
        -:  242:
  2700500:  243:  fn_fail:
  2700500:  244:    *sreq_ptr = sreq;
        -:  245:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_ISTARTMSGV);
  2700500:  246:    return mpi_errno;
        -:  247:}