-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/channels/sock/src/ch3_isendv.c
        -:    0:Graph:ch3_isendv.gcno
        -:    0:Data:ch3_isendv.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 update_request
        -:   11:#undef FCNAME
        -:   12:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   13:static void update_request(MPID_Request * sreq, MPID_IOV * iov, int iov_count,
        -:   14:			   int iov_offset, MPIU_Size_t nb)
    23235:   15:{
        -:   16:    int i;
        -:   17:    MPIDI_STATE_DECL(MPID_STATE_UPDATE_REQUEST);
        -:   18:
        -:   19:    MPIDI_FUNC_ENTER(MPID_STATE_UPDATE_REQUEST);
        -:   20:    
    70841:   21:    for (i = 0; i < iov_count; i++)
        -:   22:    {
    47606:   23:	sreq->dev.iov[i] = iov[i];
        -:   24:    }
    23235:   25:    if (iov_offset == 0)
        -:   26:    {
    16904:   27:	MPIU_Assert(iov[0].MPID_IOV_LEN == sizeof(MPIDI_CH3_Pkt_t));
    16904:   28:	sreq->dev.pending_pkt = *(MPIDI_CH3_PktGeneric_t *) iov[0].MPID_IOV_BUF;
    16904:   29:	sreq->dev.iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) &sreq->dev.pending_pkt;
        -:   30:    }
    23235:   31:    sreq->dev.iov[iov_offset].MPID_IOV_BUF = 
        -:   32:	(MPID_IOV_BUF_CAST)((char *) sreq->dev.iov[iov_offset].MPID_IOV_BUF + nb );
    23235:   33:    sreq->dev.iov[iov_offset].MPID_IOV_LEN -= nb;
    23235:   34:    sreq->dev.iov_count = iov_count;
        -:   35:
        -:   36:    MPIDI_FUNC_EXIT(MPID_STATE_UPDATE_REQUEST);
    23235:   37:}
        -:   38:
        -:   39:#undef FUNCNAME
        -:   40:#define FUNCNAME MPIDI_CH3_iSendv
        -:   41:#undef FCNAME
        -:   42:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   43:int MPIDI_CH3_iSendv(MPIDI_VC_t * vc, MPID_Request * sreq, 
        -:   44:		     MPID_IOV * iov, int n_iov)
  7385125:   45:{
  7385125:   46:    int mpi_errno = MPI_SUCCESS;
  7385125:   47:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)vc->channel_private;
        -:   48:    int (*reqFn)(MPIDI_VC_t *, MPID_Request *, int *);
        -:   49:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_ISENDV);
        -:   50:
        -:   51:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_ISENDV);
        -:   52:
  7385125:   53:    MPIU_Assert(n_iov <= MPID_IOV_LIMIT);
  7385125:   54:    MPIU_Assert(iov[0].MPID_IOV_LEN <= sizeof(MPIDI_CH3_Pkt_t))
        -:   55:
        -:   56:    /* The sock channel uses a fixed length header, the size of which is the 
        -:   57:       maximum of all possible packet headers */
  7385125:   58:    iov[0].MPID_IOV_LEN = sizeof(MPIDI_CH3_Pkt_t);
        -:   59:    MPIU_DBG_STMT(CH3_CHANNEL,VERBOSE,
        -:   60:	 MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t *)iov[0].MPID_IOV_BUF));
        -:   61:
  7385125:   62:    if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTED) /* MT */
        -:   63:    {
        -:   64:	/* Connection already formed.  If send queue is empty attempt to send 
        -:   65:	   data, queuing any unsent data. */
  7381763:   66:	if (MPIDI_CH3I_SendQ_empty(vcch)) /* MT */
        -:   67:	{
        -:   68:	    MPIU_Size_t nb;
        -:   69:	    int rc;
        -:   70:
        -:   71:	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:   72:			 "send queue empty, attempting to write");
        -:   73:	    
        -:   74:	    MPIU_DBG_PKT(vcch->conn,(MPIDI_CH3_Pkt_t*)iov[0].MPID_IOV_BUF,
        -:   75:			 "isendv");
        -:   76:	    /* MT - need some signalling to lock down our right to use the 
        -:   77:	       channel, thus insuring that the progress engine does
        -:   78:               also try to write */
        -:   79:
        -:   80:	    /* FIXME: the current code only agressively writes the first IOV.  
        -:   81:	       Eventually it should be changed to agressively write
        -:   82:               as much as possible.  Ideally, the code would be shared between 
        -:   83:	       the send routines and the progress engine. */
  7368255:   84:	    rc = MPIDU_Sock_writev(vcch->sock, iov, n_iov, &nb);
  7368255:   85:	    if (rc == MPI_SUCCESS)
        -:   86:	    {
  7368255:   87:		int offset = 0;
        -:   88:
        -:   89:		MPIU_DBG_MSG_D(CH3_CHANNEL,VERBOSE,
        -:   90:			       "wrote %ld bytes", (unsigned long) nb);
        -:   91:		
 29883629:   92:		while (offset < n_iov)
        -:   93:		{
 15153484:   94:		    if ((int)iov[offset].MPID_IOV_LEN <= nb)
        -:   95:		    {
 15147119:   96:			nb -= iov[offset].MPID_IOV_LEN;
 15147119:   97:			offset++;
        -:   98:		    }
        -:   99:		    else
        -:  100:		    {
        -:  101:			MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:  102:			     "partial write, request enqueued at head");
     6365:  103:			update_request(sreq, iov, n_iov, offset, nb);
     6365:  104:			MPIDI_CH3I_SendQ_enqueue_head(vcch, sreq);
        -:  105:			MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,
        -:  106:    (MPIU_DBG_FDEST,"posting writev, vc=0x%p, sreq=0x%08x", vc, sreq->handle));
     6365:  107:			vcch->conn->send_active = sreq;
     6365:  108:			mpi_errno = MPIDU_Sock_post_writev(vcch->conn->sock, 
        -:  109:					   sreq->dev.iov + offset,
        -:  110:					   sreq->dev.iov_count - offset, NULL);
        -:  111:			/* --BEGIN ERROR HANDLING-- */
     6365:  112:			if (mpi_errno != MPI_SUCCESS)
        -:  113:			{
    #####:  114:			    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  115:							     "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p",
        -:  116:							     sreq, vcch->conn, vc);
        -:  117:			}
        -:  118:			/* --END ERROR HANDLING-- */
        -:  119:
        -:  120:			break;
        -:  121:		    }
        -:  122:
        -:  123:		}
  7368255:  124:		if (offset == n_iov)
        -:  125:		{
        -:  126:		    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
        -:  127:				 "write complete, calling OnDataAvail fcn");
  7361890:  128:		    reqFn = sreq->dev.OnDataAvail;
  7361890:  129:		    if (!reqFn) {
  7357677:  130:			MPIU_Assert(MPIDI_Request_get_type(sreq)!=MPIDI_REQUEST_TYPE_GET_RESP);
  7357677:  131:			MPIDI_CH3U_Request_complete(sreq);
        -:  132:		    }
        -:  133:		    else {
        -:  134:			int complete;
     4213:  135:			mpi_errno = reqFn( vc, sreq, &complete );
     4213:  136:			if (mpi_errno) MPIU_ERR_POP(mpi_errno);
     4213:  137:			if (!complete) {
       97:  138:			    MPIDI_CH3I_SendQ_enqueue_head(vcch, sreq);
        -:  139:			    MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,
        -:  140:    (MPIU_DBG_FDEST,"posting writev, vc=0x%p, sreq=0x%08x", vc, sreq->handle));
       97:  141:			    vcch->conn->send_active = sreq;
       97:  142:			    mpi_errno = MPIDU_Sock_post_writev(
        -:  143:				vcch->conn->sock, sreq->dev.iov, 
        -:  144:				sreq->dev.iov_count, NULL);
        -:  145:			    /* --BEGIN ERROR HANDLING-- */
       97:  146:			    if (mpi_errno != MPI_SUCCESS)
        -:  147:			    {
    #####:  148:				mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  149:								 "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p",
        -:  150:								 sreq, vcch->conn, vc);
        -:  151:			    }
        -:  152:			    /* --END ERROR HANDLING-- */
        -:  153:			}
        -:  154:		    }
        -:  155:		}
        -:  156:	    }
        -:  157:	    /* --BEGIN ERROR HANDLING-- */
    #####:  158:	    else if (MPIR_ERR_GET_CLASS(rc) == MPIDU_SOCK_ERR_NOMEM)
        -:  159:	    {
        -:  160:		MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,
        -:  161:			     "MPIDU_Sock_writev failed, out of memory");
    #####:  162:		sreq->status.MPI_ERROR = MPIR_ERR_MEMALLOCFAILED;
        -:  163:	    }
        -:  164:	    else
        -:  165:	    {
        -:  166:		MPIU_DBG_MSG_D(CH3_CHANNEL,TYPICAL,
        -:  167:			       "MPIDU_Sock_writev failed, rc=%d", rc);
        -:  168:		/* Connection just failed.  Mark the request complete and 
        -:  169:		   return an error. */
        -:  170:		MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_FAILED);
        -:  171:		/* FIXME: Shouldn't the vc->state also change? */
        -:  172:
    #####:  173:		vcch->state = MPIDI_CH3I_VC_STATE_FAILED;
    #####:  174:		sreq->status.MPI_ERROR = MPIR_Err_create_code( rc,
        -:  175:			       MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  176:			       MPI_ERR_INTERN, "**ch3|sock|writefailed", 
        -:  177:			       "**ch3|sock|writefailed %d", rc );
        -:  178:		 /* MT - CH3U_Request_complete performs write barrier */
    #####:  179:		MPIDI_CH3U_Request_complete(sreq);
        -:  180:		/* Return error to calling routine */
    #####:  181:		mpi_errno = sreq->status.MPI_ERROR;
        -:  182:	    }
        -:  183:	    /* --END ERROR HANDLING-- */
        -:  184:	}
        -:  185:	else
        -:  186:	{
        -:  187:	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"send queue not empty, enqueuing");
    13508:  188:	    update_request(sreq, iov, n_iov, 0, 0);
    13508:  189:	    MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  190:	}
        -:  191:    }
     3362:  192:    else if (vcch->state == MPIDI_CH3I_VC_STATE_CONNECTING)
        -:  193:    {
        -:  194:	/* queuing the data so it can be sent later. */
        -:  195:	MPIU_DBG_VCUSE(vc,"connecting.  Enqueuing request");
      982:  196:	update_request(sreq, iov, n_iov, 0, 0);
      982:  197:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  198:    }
     2380:  199:    else if (vcch->state == MPIDI_CH3I_VC_STATE_UNCONNECTED)
        -:  200:    {
        -:  201:	/* Form a new connection, queuing the data so it can be sent later. */
        -:  202:	MPIU_DBG_VCUSE(vc,"unconnected.  Enqueuing request");
     2380:  203:	update_request(sreq, iov, n_iov, 0, 0);
     2380:  204:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
     2380:  205:	mpi_errno = MPIDI_CH3I_VC_post_connect(vc);
     2380:  206:	if (mpi_errno) {
    #####:  207:	    MPIU_ERR_POP(mpi_errno);
        -:  208:	}
        -:  209:    }
    #####:  210:    else if (vcch->state != MPIDI_CH3I_VC_STATE_FAILED)
        -:  211:    {
        -:  212:	/* Unable to send data at the moment, so queue it for later */
        -:  213:	MPIU_DBG_VCUSE(vc,"still connecting.  enqueuing request");
    #####:  214:	update_request(sreq, iov, n_iov, 0, 0);
    #####:  215:	MPIDI_CH3I_SendQ_enqueue(vcch, sreq);
        -:  216:    }
        -:  217:    /* --BEGIN ERROR HANDLING-- */
        -:  218:    else
        -:  219:    {
        -:  220:	MPIU_DBG_VCUSE(vc,"connection failed");
        -:  221:	/* Connection failed.  Mark the request complete and return an error. */
        -:  222:	/* TODO: Create an appropriate error message */
    #####:  223:	sreq->status.MPI_ERROR = MPI_ERR_INTERN;
        -:  224:	/* MT - CH3U_Request_complete performs write barrier */
    #####:  225:	MPIDI_CH3U_Request_complete(sreq);
        -:  226:    }
        -:  227:    /* --END ERROR HANDLING-- */
        -:  228:
  7385125:  229: fn_fail:
        -:  230:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_ISENDV);
  7385125:  231:    return mpi_errno;
        -:  232:}
        -:  233: